Ejemplo n.º 1
0
        public static Type FindDataSourceAndCheckPermissions(
            this IDomainModel DomainModel,
            IPermissionManager Permissions,
            IPrincipal principal,
            string domainName)
        {
            if (string.IsNullOrEmpty(domainName))
            {
                throw new ArgumentException("Domain object name not provided.");
            }
            var domainObjectType = DomainModel.Find(domainName);

            if (domainObjectType == null)
            {
                throw new ArgumentException("Couldn't find domain object: {0}".With(domainName));
            }
            if (!typeof(IDataSource).IsAssignableFrom(domainObjectType))
            {
                throw new ArgumentException(@"Specified type ({0}) is not a data source. 
Please check your arguments.".With(domainName));
            }
            if (!Permissions.CanAccess(domainObjectType.FullName, principal))
            {
                throw new SecurityException("You don't have permission to access: {0}.".With(domainName));
            }
            return(domainObjectType);
        }
Ejemplo n.º 2
0
            public Stream Find(string uri)
            {
                if (!Permissions.CanAccess(typeof(T)))
                {
                    return(Explain("You don't have permission to access: " + typeof(T)));
                }
                var aggs     = Cache.Find(new[] { uri });
                var filtered = Permissions.ApplyFilters(aggs);

                if (filtered.Length == 1)
                {
                    ThreadContext.Response.StatusCode = HttpStatusCode.OK;
                    var cms = ChunkedMemoryStream.Create();
                    var ct  = Serialization.Serialize(filtered[0], ThreadContext.Request.Accept, cms);
                    ThreadContext.Response.ContentType   = ct;
                    ThreadContext.Response.ContentLength = cms.Position;
                    cms.Position = 0;
                    return(cms);
                }
                ThreadContext.Response.StatusCode = HttpStatusCode.NotFound;
                return(Explain("Can't find " + typeof(T).FullName + " with Uri: " + uri));
            }
Ejemplo n.º 3
0
 public static Type FindDataSourceAndCheckPermissions(
     this IDomainModel DomainModel,
     IPermissionManager Permissions,
     string domainName)
 {
     if (string.IsNullOrEmpty(domainName))
         throw new ArgumentException("Domain object name not provided.");
     var domainObjectType = DomainModel.Find(domainName);
     if (domainObjectType == null)
         throw new ArgumentException("Couldn't find domain object: {0}".With(domainName));
     if (!typeof(IDataSource).IsAssignableFrom(domainObjectType))
         throw new ArgumentException(@"Specified type ({0}) is not a data source.
     Please check your arguments.".With(domainName));
     if (!Permissions.CanAccess(domainObjectType))
         throw new SecurityException("You don't have permission to access: {0}.".With(domainName));
     return domainObjectType;
 }
Ejemplo n.º 4
0
        public static DataTable PopulateTable <TInput, TOutput>(
            ISerialization <TInput> input,
            ISerialization <TOutput> output,
            IServiceProvider Locator,
            IDomainModel DomainModel,
            Argument <TInput> argument,
            IPrincipal principal,
            IPermissionManager permissions)
        {
            var cubeType = DomainModel.Find(argument.CubeName);

            if (cubeType == null)
            {
                throw new ArgumentException(
                          "Couldn't find cube type {0}.".With(argument.CubeName),
                          new FrameworkException(@"Example argument: 
" + CommandResult <TOutput> .ConvertToString(CreateExampleArgument(output))));
            }

            if (!permissions.CanAccess(cubeType.FullName, principal))
            {
                throw new SecurityException("You don't have permission to access: {0}.".With(argument.CubeName));
            }

            var findImpl = cubeType.GetInterfaces().FirstOrDefault(it => it.IsGenericType && it.GetGenericTypeDefinition() == typeof(IOlapCubeQuery <>));

            if (findImpl == null)
            {
                throw new ArgumentException("Cube type {0} is not IOlapCubeQuery<>.".With(cubeType.FullName));
            }

            var sourceType = findImpl.GetGenericArguments()[0];

            IAnalyzeData command;

            if (string.IsNullOrEmpty(argument.SpecificationName))
            {
                var commandType = typeof(AnalyzeSpecification <,>).MakeGenericType(cubeType, sourceType);
                command = (IAnalyzeData)Activator.CreateInstance(commandType);
            }
            else
            {
                var specificationType =
                    DomainModel.FindNested(argument.CubeName, argument.SpecificationName)
                    ?? DomainModel.Find(argument.SpecificationName);
                if (specificationType == null)
                {
                    throw new ArgumentException("Couldn't find specification: {0}".With(argument.SpecificationName));
                }
                var commandType = typeof(AnalyzeWithSpecification <, ,>).MakeGenericType(cubeType, sourceType, specificationType);
                command = (IAnalyzeData)Activator.CreateInstance(commandType);
            }
            return
                (command.Analyze(
                     input,
                     Locator,
                     argument.Dimensions,
                     argument.Facts,
                     argument.Order,
                     argument.Limit,
                     argument.Offset,
                     argument.Specification));
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Check if current principal bound to thread can access some resource.
        /// Resource identity will be provided from target type argument full name.
        /// </summary>
        /// <param name="manager">permission service</param>
        /// <param name="target">type argument</param>
        /// <returns>is user allowed to access requested resource</returns>
        public static bool CanAccess(this IPermissionManager manager, Type target)
        {
            Contract.Requires(manager != null);

            return(manager.CanAccess(target.FullName, Thread.CurrentPrincipal));
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Check if current principal bound to thread can access some resource.
        /// Resource identity will be provided from type full name.
        /// </summary>
        /// <typeparam name="T">object type</typeparam>
        /// <param name="manager">permission service</param>
        /// <returns>is user allowed to access requested resource</returns>
        public static bool CanAccess <T>(this IPermissionManager manager)
        {
            Contract.Requires(manager != null);

            return(manager.CanAccess(typeof(T).FullName, Thread.CurrentPrincipal));
        }
Ejemplo n.º 7
0
        public ICommandResult <TOutput> Execute <TInput, TOutput>(
            IServiceProvider locator,
            ISerialization <TInput> input,
            ISerialization <TOutput> output,
            IPrincipal principal,
            TInput data)
        {
            var either = CommandResult <TOutput> .Check <Argument <TInput>, TInput>(input, output, data, CreateExampleArgument);

            if (either.Error != null)
            {
                return(either.Error);
            }
            var argument = either.Argument;

            var documentType = DomainModel.FindNested(argument.CubeName, argument.TemplaterName);

            if (documentType == null)
            {
                return(CommandResult <TOutput> .Fail(
                           "Couldn't find Templater type {0} for {1}.".With(argument.TemplaterName, argument.CubeName),
                           @"Example argument: 
" + CommandResult <TOutput> .ConvertToString(CreateExampleArgument(output))));
            }

            if (!Permissions.CanAccess(documentType.FullName, principal))
            {
                return(CommandResult <TOutput> .Forbidden("{0} in {1}.".With(argument.TemplaterName, argument.CubeName)));
            }
            if (!typeof(IDocumentReport <DataTable>).IsAssignableFrom(documentType))
            {
                return
                    (CommandResult <TOutput> .Fail(
                         "Templater type {0} for {1} is not IDocumentReport<DataTable>. Check {0}.".With(
                             documentType.FullName,
                             argument.CubeName),
                         null));
            }

            IDocumentReport <DataTable> report;

            try
            {
                report = locator.Resolve <IDocumentReport <DataTable> >(documentType);
            }
            catch (Exception ex)
            {
                return(CommandResult <TOutput> .Fail(
                           @"Can't create document report. Is report {0} registered in system?".With(documentType.FullName),
                           ex.GetDetailedExplanation()));
            }
            try
            {
                var table  = AnalyzeOlapCube.PopulateTable(input, output, locator, DomainModel, argument, principal, Permissions);
                var result = report.Create(table);
                return(CommandResult <TOutput> .Return(HttpStatusCode.Created, Serialize(output, result), "Report created"));
            }
            catch (ArgumentException ex)
            {
                return(CommandResult <TOutput> .Fail(
                           ex.Message,
                           ex.GetDetailedExplanation() + @"
Example argument: 
" + CommandResult <TOutput> .ConvertToString(CreateExampleArgument(output))));
            }
        }
Ejemplo n.º 8
0
        public IProcessingResult <TOutput> Execute <TInput, TOutput>(IServerCommandDescription <TInput>[] commandDescriptions)
        {
            var stopwatch = Stopwatch.StartNew();

            if (commandDescriptions == null || commandDescriptions.Length == 0)
            {
                return
                    (ProcessingResult <TOutput> .Create(
                         "There are no commands to execute.",
                         HttpStatusCode.BadRequest,
                         null,
                         stopwatch.ElapsedMilliseconds));
            }

            var inputSerializer  = Scope.Resolve <ISerialization <TInput> >();
            var outputSerializer = Scope.Resolve <ISerialization <TOutput> >();

            var executedCommands = new List <ICommandResultDescription <TOutput> >();

            try
            {
                foreach (var c in commandDescriptions)
                {
                    if (!Permissions.CanAccess(c.CommandType))
                    {
                        LogFactory.Create("Processing context").Trace(
                            () => "Access denied. User: {0}. Target: {1}.".With(
                                Thread.CurrentPrincipal.Identity.Name,
                                c.CommandType.FullName));
                        return
                            (ProcessingResult <TOutput> .Create(
                                 "You don't have permission to execute command: " + c.CommandType.FullName,
                                 HttpStatusCode.Forbidden,
                                 executedCommands,
                                 stopwatch.ElapsedMilliseconds));
                    }
                }

                foreach (var cd in commandDescriptions)
                {
                    var command = Scope.Resolve <IServerCommand>(cd.CommandType);
                    var result  = command.Execute(inputSerializer, outputSerializer, cd.Data);
                    if (result == null)
                    {
                        throw new FrameworkException("Result returned null for " + cd.CommandType);
                    }
                    executedCommands.Add(CommandResultDescription <TOutput> .Create(cd.RequestID, result));
                    if ((int)result.Status >= 400)
                    {
                        return(ProcessingResult <TOutput> .Create(
                                   result.Message,
                                   result.Status,
                                   executedCommands,
                                   stopwatch.ElapsedMilliseconds));
                    }
                }

                return
                    (ProcessingResult <TOutput> .Create(
                         "Commands executed in: {0} ms.".With(stopwatch.ElapsedMilliseconds),
                         HttpStatusCode.OK,
                         executedCommands,
                         stopwatch.ElapsedMilliseconds));
            }
            catch (SecurityException ex)
            {
                LogFactory.Create("Processing context").Trace(
                    () => "Security error. User: {0}. Error: {1}.".With(
                        Thread.CurrentPrincipal.Identity.Name,
                        ex.ToString()));
                return
                    (ProcessingResult <TOutput> .Create(
                         "You don't have authorization to perform requested action: {0}".With(ex.Message),
                         HttpStatusCode.Forbidden,
                         executedCommands,
                         stopwatch.ElapsedMilliseconds));
            }
            catch (AggregateException ex)
            {
                LogFactory.Create("Processing context").Trace(
                    () => "Multiple errors. User: {0}. Error: {1}.".With(
                        Thread.CurrentPrincipal.Identity.Name,
                        ex.GetDetailedExplanation()));
                return(Exceptions.DebugMode
                                        ? ProcessingResult <TOutput> .Create(
                           ex.GetDetailedExplanation(),
                           HttpStatusCode.InternalServerError,
                           executedCommands,
                           stopwatch.ElapsedMilliseconds)
                                        : ProcessingResult <TOutput> .Create(
                           string.Join(Environment.NewLine, ex.InnerExceptions.Select(it => it.Message)),
                           HttpStatusCode.InternalServerError,
                           executedCommands,
                           stopwatch.ElapsedMilliseconds));
            }
            catch (OutOfMemoryException ex)
            {
                LogFactory.Create("Processing context").Error("Out of memory error. Error: " + ex.GetDetailedExplanation());
                return(Exceptions.DebugMode
                                        ? ProcessingResult <TOutput> .Create(
                           ex.GetDetailedExplanation(),
                           HttpStatusCode.ServiceUnavailable,
                           executedCommands,
                           stopwatch.ElapsedMilliseconds)
                                        : ProcessingResult <TOutput> .Create(
                           ex.Message,
                           HttpStatusCode.ServiceUnavailable,
                           executedCommands,
                           stopwatch.ElapsedMilliseconds));
            }
            catch (Exception ex)
            {
                LogFactory.Create("Processing context").Trace(
                    () => "Unexpected error. User: {0}. Error: {1}.".With(
                        Thread.CurrentPrincipal.Identity.Name,
                        ex.GetDetailedExplanation()));
                return(Exceptions.DebugMode
                                        ? ProcessingResult <TOutput> .Create(
                           ex.GetDetailedExplanation(),
                           HttpStatusCode.InternalServerError,
                           executedCommands,
                           stopwatch.ElapsedMilliseconds)
                                        : ProcessingResult <TOutput> .Create(
                           ex.Message,
                           HttpStatusCode.InternalServerError,
                           executedCommands,
                           stopwatch.ElapsedMilliseconds));
            }
        }
Ejemplo n.º 9
0
        public IProcessingResult <TOutput> Execute <TInput, TOutput>(
            IServerCommandDescription <TInput>[] commandDescriptions,
            IPrincipal principal)
        {
            var start = Stopwatch.GetTimestamp();

            if (commandDescriptions == null || commandDescriptions.Length == 0)
            {
                TraceSource.TraceEvent(TraceEventType.Warning, 5310);
                return
                    (ProcessingResult <TOutput> .Create(
                         "There are no commands to execute.",
                         HttpStatusCode.BadRequest,
                         null,
                         start));
            }

            var inputSerializer  = (ISerialization <TInput>)Scope.GetService(typeof(ISerialization <TInput>));
            var outputSerializer = (ISerialization <TOutput>)Scope.GetService(typeof(ISerialization <TOutput>));

            var executedCommands = new List <ICommandResultDescription <TOutput> >();

            try
            {
                foreach (var c in commandDescriptions)
                {
                    if (!Permissions.CanAccess(c.CommandType.FullName, principal))
                    {
                        TraceSource.TraceEvent(
                            TraceEventType.Warning,
                            5311,
                            "Access denied. User: {0}. Target: {1}",
                            principal.Identity.Name,
                            c.CommandType.FullName);
                        return
                            (ProcessingResult <TOutput> .Create(
                                 "You don't have permission to execute command: " + c.CommandType.FullName,
                                 HttpStatusCode.Forbidden,
                                 executedCommands,
                                 start));
                    }
                }

                foreach (var cd in commandDescriptions)
                {
                    var startCommand = Stopwatch.GetTimestamp();
                    var command      = (IServerCommand)Scope.GetService(cd.CommandType);
                    var result       = command.Execute(Scope, inputSerializer, outputSerializer, principal, cd.Data);
                    if (result == null)
                    {
                        throw new FrameworkException("Result returned null for " + cd.CommandType);
                    }
                    executedCommands.Add(CommandResultDescription <TOutput> .Create(cd.RequestID, result, startCommand));
                    if ((int)result.Status >= 400)
                    {
                        return(ProcessingResult <TOutput> .Create(
                                   result.Message,
                                   result.Status,
                                   executedCommands,
                                   start));
                    }
                }

                var duration = (decimal)(Stopwatch.GetTimestamp() - start) / TimeSpan.TicksPerMillisecond;
                return
                    (ProcessingResult <TOutput> .Create(
                         "Commands executed in: " + duration.ToString(CultureInfo.InvariantCulture) + " ms",
                         HttpStatusCode.OK,
                         executedCommands,
                         start));
            }
            catch (SecurityException ex)
            {
                TraceSource.TraceEvent(
                    TraceEventType.Warning,
                    5312,
                    "Security error. User: {0}. Error: {1}.",
                    principal.Identity.Name,
                    ex);
                return
                    (ProcessingResult <TOutput> .Create(
                         "You don't have authorization to perform requested action: {0}".With(ex.Message),
                         HttpStatusCode.Forbidden,
                         executedCommands,
                         start));
            }
            catch (AggregateException ex)
            {
                TraceSource.TraceEvent(
                    TraceEventType.Error,
                    5313,
                    "Multiple errors. User: {0}. Error: {1}.",
                    principal.Identity.Name,
                    ex.GetDetailedExplanation());
                return(Exceptions.DebugMode
                                        ? ProcessingResult <TOutput> .Create(
                           ex.GetDetailedExplanation(),
                           HttpStatusCode.InternalServerError,
                           executedCommands,
                           start)
                                        : ProcessingResult <TOutput> .Create(
                           string.Join(Environment.NewLine, ex.InnerExceptions.Select(it => it.Message)),
                           HttpStatusCode.InternalServerError,
                           executedCommands,
                           start));
            }
            catch (OutOfMemoryException ex)
            {
                TraceSource.TraceEvent(TraceEventType.Critical, 5315, ex.GetDetailedExplanation());
                return(Exceptions.DebugMode
                                        ? ProcessingResult <TOutput> .Create(
                           ex.GetDetailedExplanation(),
                           HttpStatusCode.ServiceUnavailable,
                           executedCommands,
                           start)
                                        : ProcessingResult <TOutput> .Create(
                           ex.Message,
                           HttpStatusCode.ServiceUnavailable,
                           executedCommands,
                           start));
            }
            catch (DbException ex)
            {
                TraceSource.TraceEvent(TraceEventType.Warning, 5316, ex.GetDetailedExplanation());
                return(Exceptions.DebugMode
                                        ? ProcessingResult <TOutput> .Create(
                           ex.GetDetailedExplanation(),
                           HttpStatusCode.Conflict,
                           executedCommands,
                           start)
                                        : ProcessingResult <TOutput> .Create(
                           ex.Message,
                           HttpStatusCode.Conflict,
                           executedCommands,
                           start));
            }
            catch (Exception ex)
            {
                TraceSource.TraceEvent(
                    TraceEventType.Error,
                    5317,
                    "Unexpected error. User: {0}. Error: {1}",
                    principal.Identity.Name,
                    ex.GetDetailedExplanation());
                return(Exceptions.DebugMode
                                        ? ProcessingResult <TOutput> .Create(
                           ex.GetDetailedExplanation(),
                           HttpStatusCode.InternalServerError,
                           executedCommands,
                           start)
                                        : ProcessingResult <TOutput> .Create(
                           ex.Message,
                           HttpStatusCode.InternalServerError,
                           executedCommands,
                           start));
            }
        }
Ejemplo n.º 10
0
        public static DataTable PopulateTable <TInput, TOutput>(
            ISerialization <TInput> input,
            ISerialization <TOutput> output,
            IServiceLocator Locator,
            IDomainModel DomainModel,
            Argument <TInput> argument,
            IPermissionManager Permissions)
        {
            var cubeType = DomainModel.Find(argument.CubeName);

            if (cubeType == null)
            {
                throw new ArgumentException(
                          "Couldn't find cube type {0}.".With(argument.CubeName),
                          new FrameworkException(@"Example argument: 
" + CommandResult <TOutput> .ConvertToString(CreateExampleArgument(output))));
            }

            if (!Permissions.CanAccess(cubeType))
            {
                throw new SecurityException("You don't have permission to access: {0}.".With(argument.CubeName));
            }

            if (!typeof(IOlapCubeQuery).IsAssignableFrom(cubeType))
            {
                throw new ArgumentException("Cube type {0} is not IOlapCubeQuery.".With(cubeType.FullName));
            }

            IOlapCubeQuery query;

            try
            {
                query = Locator.Resolve <IOlapCubeQuery>(cubeType);
            }
            catch (Exception ex)
            {
                throw new ArgumentException(
                          "Can't create cube query. Is query {0} registered in system?".With(cubeType.FullName),
                          ex);
            }

            if (string.IsNullOrEmpty(argument.SpecificationName) && argument.Specification == null)
            {
                return(query.Analyze(argument.Dimensions, argument.Facts, argument.Order, argument.Limit, argument.Offset));
            }
            else if (string.IsNullOrEmpty(argument.SpecificationName))
            {
                dynamic specification;
                try
                {
                    specification = input.Deserialize <TInput, dynamic>(argument.Specification, Locator);
                }
                catch (Exception ex)
                {
                    throw new ArgumentException(
                              "Specification could not be deserialized.",
                              new FrameworkException(@"Please provide specification name. Error: {0}.".With(ex.Message), ex));
                }
                if (specification == null)
                {
                    throw new ArgumentException(
                              "Specification could not be deserialized.",
                              new FrameworkException("Please provide specification name."));
                }
                return(query.Analyze(argument.Dimensions, argument.Facts, argument.Order, specification, argument.Limit, argument.Offset));
            }
            else
            {
                var specificationType =
                    DomainModel.FindNested(argument.CubeName, argument.SpecificationName)
                    ?? DomainModel.Find(argument.SpecificationName);
                if (specificationType == null)
                {
                    throw new ArgumentException("Couldn't find specification: {0}".With(argument.SpecificationName));
                }
                var commandType = typeof(AnalyzeWithSpecification <>).MakeGenericType(specificationType);
                var command     = (IAnalyzeData)Activator.CreateInstance(commandType);
                return
                    (command.Analyze(
                         input,
                         Locator,
                         query,
                         argument.Dimensions,
                         argument.Facts,
                         argument.Order,
                         argument.Limit,
                         argument.Offset,
                         argument.Specification));
            }
        }
Ejemplo n.º 11
0
        public IProcessingResult <TOutput> Execute <TInput, TOutput>(IServerCommandDescription <TInput>[] commandDescriptions)
        {
            if (commandDescriptions == null || commandDescriptions.Length == 0)
            {
                return
                    (ProcessingResult <TOutput> .Create(
                         "There are no commands to execute.",
                         HttpStatusCode.BadRequest,
                         null,
                         0));
            }

            var stopwatch = Stopwatch.StartNew();

            foreach (var c in commandDescriptions)
            {
                if (!Permissions.CanAccess(c.CommandType))
                {
                    Logger.Trace(
                        () => "Access denied. User: {0}. Target: {1}.".With(
                            Thread.CurrentPrincipal.Identity.Name,
                            c.CommandType.FullName));
                    return
                        (ProcessingResult <TOutput> .Create(
                             "You don't have permission to execute command: " + c.CommandType.FullName,
                             HttpStatusCode.Forbidden,
                             null,
                             stopwatch.ElapsedMilliseconds));
                }
            }

            var inputSerializer  = GetSerializer <TInput>();
            var outputSerializer = GetSerializer <TOutput>();

            var commands       = new CommandInfo <TInput> [commandDescriptions.Length];
            var useTransaction = false;

            for (int i = 0; i < commands.Length; i++)
            {
                var c = commands[i] = new CommandInfo <TInput>(commandDescriptions[i], ActualCommands);
                useTransaction = useTransaction || !c.IsReadOnly;
                if (c.Target == null)
                {
                    Logger.Trace(
                        () => "Unknown target. User: {0}. Target: {1}.".With(
                            Thread.CurrentPrincipal.Identity.Name,
                            commandDescriptions[i].CommandType.FullName));
                    return
                        (ProcessingResult <TOutput> .Create(
                             "Unknown command: {0}. Check if requested command is registered in the system".With(
                                 c.Description.CommandType),
                             HttpStatusCode.BadRequest,
                             null,
                             stopwatch.ElapsedMilliseconds));
                }
            }

            var scopeID = useTransaction ? Guid.NewGuid().ToString() : null;

            using (var scope = ObjectFactory.CreateScope(scopeID))
            {
                var            executedCommands = new List <ICommandResultDescription <TOutput> >(commandDescriptions.Length);
                IDatabaseQuery query            = null;
                try
                {
                    try
                    {
                        query = TransactionManager.StartQuery(useTransaction);
                    }
                    catch (Exception ex)
                    {
                        Logger.Error("Can't start query. Error: " + ex.ToString());
                        return(Exceptions.DebugMode
                                                        ? ProcessingResult <TOutput> .Create(
                                   ex.ToString(),
                                   HttpStatusCode.ServiceUnavailable,
                                   null,
                                   stopwatch.ElapsedMilliseconds)
                                                        : ProcessingResult <TOutput> .Create(
                                   "Unable to create database connection",
                                   HttpStatusCode.ServiceUnavailable,
                                   null,
                                   stopwatch.ElapsedMilliseconds));
                    }
                    scope.RegisterInstance(query);
                    if (useTransaction)
                    {
                        scope.RegisterInstance <IEnumerable <IServerCommandDescription <TInput> > >(commandDescriptions);
                        scope.RegisterInstance <IEnumerable <ICommandResultDescription <TOutput> > >(executedCommands);
                        scope.RegisterType(typeof(ProcessingContext), typeof(IProcessingEngine), InstanceScope.Singleton);
                    }
                    foreach (var cmd in commands)
                    {
                        var result = cmd.GetCommand(scope).Execute(inputSerializer, outputSerializer, cmd.Description.Data);
                        if (result == null)
                        {
                            throw new FrameworkException("Result returned null for " + cmd.Target.FullName);
                        }
                        executedCommands.Add(CommandResultDescription <TOutput> .Create(cmd.Description.RequestID, result));
                        if ((int)result.Status >= 400)
                        {
                            TransactionManager.EndQuery(query, false);
                            return(ProcessingResult <TOutput> .Create(
                                       result.Message,
                                       result.Status,
                                       executedCommands,
                                       stopwatch.ElapsedMilliseconds));
                        }
                    }

                    TransactionManager.EndQuery(query, true);
                    return
                        (ProcessingResult <TOutput> .Create(
                             "Commands executed in: " + stopwatch.ElapsedMilliseconds.ToString() + " ms.",
                             HttpStatusCode.OK,
                             executedCommands,
                             stopwatch.ElapsedMilliseconds));
                }
                catch (SecurityException ex)
                {
                    Logger.Trace(
                        () => "Security error. User: {0}. Error: {1}.".With(
                            Thread.CurrentPrincipal.Identity.Name,
                            ex.ToString()));
                    TransactionManager.EndQuery(query, false);
                    return
                        (ProcessingResult <TOutput> .Create(
                             "You don't have authorization to perform requested action: " + ex.Message,
                             HttpStatusCode.Forbidden,
                             executedCommands,
                             stopwatch.ElapsedMilliseconds));
                }
                catch (AggregateException ex)
                {
                    Logger.Trace(
                        () => "Multiple errors. User: {0}. Error: {1}.".With(
                            Thread.CurrentPrincipal.Identity.Name,
                            ex.GetDetailedExplanation()));
                    TransactionManager.EndQuery(query, false);
                    return(Exceptions.DebugMode
                                                ? ProcessingResult <TOutput> .Create(
                               ex.GetDetailedExplanation(),
                               HttpStatusCode.InternalServerError,
                               executedCommands,
                               stopwatch.ElapsedMilliseconds)
                                                : ProcessingResult <TOutput> .Create(
                               string.Join(Environment.NewLine, ex.InnerExceptions.Select(it => it.Message)),
                               HttpStatusCode.InternalServerError,
                               executedCommands,
                               stopwatch.ElapsedMilliseconds));
                }
                catch (OutOfMemoryException ex)
                {
                    Logger.Error("Out of memory error. Error: " + ex.GetDetailedExplanation());
                    TransactionManager.EndQuery(query, false);
                    return(Exceptions.DebugMode
                                                ? ProcessingResult <TOutput> .Create(
                               ex.GetDetailedExplanation(),
                               HttpStatusCode.ServiceUnavailable,
                               executedCommands,
                               stopwatch.ElapsedMilliseconds)
                                                : ProcessingResult <TOutput> .Create(
                               ex.Message,
                               HttpStatusCode.ServiceUnavailable,
                               executedCommands,
                               stopwatch.ElapsedMilliseconds));
                }
                catch (Exception ex)
                {
                    Logger.Trace(
                        () => "Unexpected error. User: {0}. Error: {1}.".With(
                            Thread.CurrentPrincipal.Identity.Name,
                            ex.GetDetailedExplanation()));
                    TransactionManager.EndQuery(query, false);
                    return(Exceptions.DebugMode
                                                ? ProcessingResult <TOutput> .Create(
                               ex.GetDetailedExplanation(),
                               HttpStatusCode.InternalServerError,
                               executedCommands,
                               stopwatch.ElapsedMilliseconds)
                                                : ProcessingResult <TOutput> .Create(
                               ex.Message,
                               HttpStatusCode.InternalServerError,
                               executedCommands,
                               stopwatch.ElapsedMilliseconds));
                }
            }
        }
Ejemplo n.º 12
0
        public IProcessingResult <TOutput> Execute <TInput, TOutput>(
            IServerCommandDescription <TInput>[] commandDescriptions,
            IPrincipal principal)
        {
            var start = Stopwatch.GetTimestamp();

            if (commandDescriptions == null || commandDescriptions.Length == 0)
            {
                TraceSource.TraceEvent(TraceEventType.Warning, 5310);
                return
                    (ProcessingResult <TOutput> .Create(
                         "There are no commands to execute.",
                         HttpStatusCode.BadRequest,
                         null,
                         start));
            }

            for (int i = 0; i < commandDescriptions.Length; i++)
            {
                var c = commandDescriptions[i];
                if (!Permissions.CanAccess(c.CommandType.FullName, principal))
                {
                    TraceSource.TraceEvent(
                        TraceEventType.Warning,
                        5311,
                        "Access denied. User: {0}. Target: {1}",
                        principal.Identity.Name,
                        c.CommandType.FullName);
                    return
                        (ProcessingResult <TOutput> .Create(
                             "You don't have permission to execute command: " + c.CommandType.FullName,
                             HttpStatusCode.Forbidden,
                             null,
                             start));
                }
            }

            var inputSerializer  = GetSerializer <TInput>();
            var outputSerializer = GetSerializer <TOutput>();

            var useTransaction = false;

            for (int i = 0; i < commandDescriptions.Length; i++)
            {
                IServerCommand command;
                var            cd = commandDescriptions[i];
                if (!ActualCommands.TryGetValue(cd.CommandType, out command))
                {
                    TraceSource.TraceEvent(
                        TraceEventType.Warning,
                        5321,
                        "Unknown target. User: {0}. Target: {1}",
                        principal.Identity.Name,
                        cd.CommandType.FullName);
                    return
                        (ProcessingResult <TOutput> .Create(
                             "Unknown command: {0}. Check if requested command is registered in the system".With(
                                 cd.CommandType),
                             HttpStatusCode.NotImplemented,
                             null,
                             start));
                }
                useTransaction = useTransaction || (command is IReadOnlyServerCommand == false);
            }

            var   executedCommands = new List <ICommandResultDescription <TOutput> >(commandDescriptions.Length);
            Scope scope            = null;

            try
            {
                try
                {
                    scope = ScopePool.Take(!useTransaction, principal);
                }
                catch (Exception ex)
                {
                    TraceSource.TraceEvent(TraceEventType.Critical, 5322, "{0}", ex);
                    return(Exceptions.DebugMode
                                                ? ProcessingResult <TOutput> .Create(
                               ex.ToString(),
                               HttpStatusCode.ServiceUnavailable,
                               null,
                               start)
                                                : ProcessingResult <TOutput> .Create(
                               "Unable to create database connection",
                               HttpStatusCode.ServiceUnavailable,
                               null,
                               start));
                }
                foreach (var cd in commandDescriptions)
                {
                    var startCommand = Stopwatch.GetTimestamp();
                    var cmd          = ActualCommands[cd.CommandType];
                    var result       = cmd.Execute(scope.Factory, inputSerializer, outputSerializer, principal, cd.Data);
                    if (result == null)
                    {
                        throw new FrameworkException("Result returned null for " + cd.CommandType.FullName);
                    }
                    executedCommands.Add(CommandResultDescription <TOutput> .Create(cd.RequestID, result, startCommand));
                    if ((int)result.Status >= 400)
                    {
                        ScopePool.Release(scope, false);
                        return(ProcessingResult <TOutput> .Create(
                                   result.Message,
                                   result.Status,
                                   executedCommands,
                                   start));
                    }
                }

                ScopePool.Release(scope, true);
                var duration = (decimal)(Stopwatch.GetTimestamp() - start) / TimeSpan.TicksPerMillisecond;
                return
                    (ProcessingResult <TOutput> .Create(
                         "Commands executed in: " + duration.ToString(CultureInfo.InvariantCulture) + " ms",
                         HttpStatusCode.OK,
                         executedCommands,
                         start));
            }
            catch (SecurityException ex)
            {
                TraceSource.TraceEvent(
                    TraceEventType.Warning,
                    5312,
                    "Security error. User: {0}. Error: {1}.",
                    principal.Identity.Name,
                    ex);
                ScopePool.Release(scope, false);
                return
                    (ProcessingResult <TOutput> .Create(
                         "You don't have authorization to perform requested action: " + ex.Message,
                         HttpStatusCode.Forbidden,
                         executedCommands,
                         start));
            }
            catch (AggregateException ex)
            {
                TraceSource.TraceEvent(
                    TraceEventType.Error,
                    5313,
                    "Multiple errors. User: {0}. Error: {1}.",
                    principal.Identity.Name,
                    ex.GetDetailedExplanation());
                ScopePool.Release(scope, false);
                return(Exceptions.DebugMode
                                        ? ProcessingResult <TOutput> .Create(
                           ex.GetDetailedExplanation(),
                           HttpStatusCode.InternalServerError,
                           executedCommands,
                           start)
                                        : ProcessingResult <TOutput> .Create(
                           string.Join(Environment.NewLine, ex.InnerExceptions.Select(it => it.Message)),
                           HttpStatusCode.InternalServerError,
                           executedCommands,
                           start));
            }
            catch (OutOfMemoryException ex)
            {
                TraceSource.TraceEvent(TraceEventType.Critical, 5315, ex.GetDetailedExplanation());
                ScopePool.Release(scope, false);
                return(Exceptions.DebugMode
                                        ? ProcessingResult <TOutput> .Create(
                           ex.GetDetailedExplanation(),
                           HttpStatusCode.ServiceUnavailable,
                           executedCommands,
                           start)
                                        : ProcessingResult <TOutput> .Create(
                           ex.Message,
                           HttpStatusCode.ServiceUnavailable,
                           executedCommands,
                           start));
            }
            catch (DbException ex)
            {
                TraceSource.TraceEvent(TraceEventType.Warning, 5316, ex.GetDetailedExplanation());
                ScopePool.Release(scope, false);
                return(Exceptions.DebugMode
                                        ? ProcessingResult <TOutput> .Create(
                           ex.GetDetailedExplanation(),
                           HttpStatusCode.Conflict,
                           executedCommands,
                           start)
                                        : ProcessingResult <TOutput> .Create(
                           ex.Message,
                           HttpStatusCode.Conflict,
                           executedCommands,
                           start));
            }
            catch (Exception ex)
            {
                TraceSource.TraceEvent(
                    TraceEventType.Error,
                    5317,
                    "Unexpected error. User: {0}. Error: {1}",
                    principal.Identity.Name,
                    ex.GetDetailedExplanation());
                ScopePool.Release(scope, false);
                return(Exceptions.DebugMode
                                        ? ProcessingResult <TOutput> .Create(
                           ex.GetDetailedExplanation(),
                           HttpStatusCode.InternalServerError,
                           executedCommands,
                           start)
                                        : ProcessingResult <TOutput> .Create(
                           ex.Message,
                           HttpStatusCode.InternalServerError,
                           executedCommands,
                           start));
            }
        }