Exemplo n.º 1
0
        public void Execute(NotificationEvent notification)
        {
            var pipeline = new DefaultPipeline <WebServiceReceiverContext>(
                Load <MessageStalenessCheckStep>(),
                Load <CheckForDuplicateStep>(),
                Load <RepublishMessageStep>());

            var result = pipeline.Execute(new WebServiceReceiverContext
            {
                Notification = notification
            });

            if (result.Success)
            {
                return;
            }

            var ex = result.StepResults.FirstOrDefault(sr => sr.Failure != null);

            if (ex != null)
            {
                // ignore staleness exceptions
                if (ex.Failure.Error is StaleMessageException)
                {
                    return;
                }

                throw new ApplicationException("Step failure", ex.Failure.Error);
            }

            throw new ApplicationException("General Pipeline failure");
        }
Exemplo n.º 2
0
        public void CanMeasureTimeSpentInSteps()
        {
            var stats    = new PipelineStepProfilerStats();
            var pipeline = new DefaultPipeline()
                           .OnReceive(new Step300())
                           .OnReceive(new Step100())
                           .OnReceive(new Step200());

            var profiler = new PipelineStepProfiler(pipeline, stats);

            var receivePipeline  = profiler.ReceivePipeline();
            var invoker          = new DefaultPipelineInvoker();
            var transportMessage = new TransportMessage(new Dictionary <string, string>(), new byte[0]);

            using (new DefaultTransactionContextScope())
            {
                var stepContext = new IncomingStepContext(transportMessage, AmbientTransactionContext.Current);

                invoker.Invoke(stepContext, receivePipeline).Wait();

                var stepStats = stats.GetStats();

                Console.WriteLine(string.Join(Environment.NewLine, stepStats));
            }
        }
Exemplo n.º 3
0
 public void Dispose()
 {
     VertexLayout.Dispose();
     VertexLayout = null;
     DefaultPipeline.Dispose();
     DefaultPipeline = null;
 }
Exemplo n.º 4
0
        public override void LoadEntity(ContainerBuilder builder, Process process, Entity entity)
        {
            if (process == null)
            {
                return;
            }

            var type = process.Pipeline == "defer" ? entity.Pipeline : process.Pipeline;

            builder.Register(ctx => {
                var context = ctx.ResolveNamed <IContext>(entity.Key);
                IPipeline pipeline;
                context.Debug(() => $"Registering {type} for entity {entity.Alias}.");
                var outputController = ctx.IsRegisteredWithName <IOutputController>(entity.Key) ? ctx.ResolveNamed <IOutputController>(entity.Key) : new NullOutputController();
                switch (type)
                {
                case "parallel.linq":
                    pipeline = new ParallelPipeline(new DefaultPipeline(outputController, context));
                    break;

                default:
                    pipeline = new DefaultPipeline(outputController, context);
                    break;
                }

                var provider = process.Output().Provider;

                // TODO: rely on IInputProvider's Read method instead (after every provider has one)
                pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IRead)) ? ctx.ResolveNamed <IRead>(entity.Key) : null);
                pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IInputProvider)) ? ctx.ResolveNamed <IInputProvider>(entity.Key) : null);

                // transform
                if (!process.ReadOnly)
                {
                    pipeline.Register(new SetSystemFields(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity)));
                }

                pipeline.Register(new DefaultTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity), context.GetAllEntityFields().Where(f => !f.System)));
                pipeline.Register(TransformFactory.GetTransforms(ctx, context, entity.GetAllFields().Where(f => f.Transforms.Any())));
                pipeline.Register(ValidateFactory.GetValidators(ctx, context, entity.GetAllFields().Where(f => f.Validators.Any())));

                if (!process.ReadOnly)
                {
                    pipeline.Register(new StringTruncateTransfom(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity)));
                    if (provider == "sqlserver")
                    {
                        pipeline.Register(new MinDateTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity), new DateTime(1753, 1, 1)));
                    }
                }

                // writer, TODO: rely on IOutputProvider instead
                pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IWrite)) ? ctx.ResolveNamed <IWrite>(entity.Key) : null);
                pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IOutputProvider)) ? ctx.ResolveNamed <IOutputProvider>(entity.Key) : null);

                // updater
                pipeline.Register(process.ReadOnly || !ctx.IsRegisteredWithName(entity.Key, typeof(IUpdate)) ? new NullUpdater() : ctx.ResolveNamed <IUpdate>(entity.Key));

                return(pipeline);
            }).Named <IPipeline>(entity.Key);
        }
Exemplo n.º 5
0
 public void TestNoExceptionsAreThrownWhenDecompiling(IManagedMethod method, IList<Instruction> instructions)
 {
     var pipeline = new DefaultPipeline().Without<LambdaInliningVisitor>();
     var elements = instructions.Select(i => (IElement)new InstructionElement(i)).ToList();
     Assert.DoesNotThrow(() => {
         try {
             ApplyPipeline(pipeline, elements, method);
         }
         catch (NotSupportedException) {
         }
     });
 }
        public override void LoadEntity(ContainerBuilder builder, Process process, Entity entity)
        {
            if (process == null)
            {
                return;
            }

            var type = process.Pipeline == "defer" ? entity.Pipeline : process.Pipeline;

            builder.Register(ctx => {
                var context = ctx.ResolveNamed <IContext>(entity.Key);
                IPipeline pipeline;
                context.Debug(() => $"Registering {type} for entity {entity.Alias}.");
                switch (type)
                {
                case "parallel.linq":
                    pipeline = new ParallelPipeline(new DefaultPipeline(ctx.ResolveNamed <IOutputController>(entity.Key), context));
                    break;

                default:
                    pipeline = new DefaultPipeline(ctx.ResolveNamed <IOutputController>(entity.Key), context);
                    break;
                }

                var provider = process.Output().Provider;

                // extract
                pipeline.Register(ctx.ResolveNamed <IRead>(entity.Key));

                // transform
                pipeline.Register(new SetBatchId(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity, entity.TflBatchId())));
                pipeline.Register(new DefaultTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity), context.GetAllEntityFields()));
                pipeline.Register(TransformFactory.GetTransforms(ctx, process, entity, entity.GetAllFields().Where(f => f.Transforms.Any())));
                pipeline.Register(new SetKey(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity, entity.TflKey())));
                pipeline.Register(new StringTruncateTransfom(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity)));

                if (provider == "sqlserver")
                {
                    pipeline.Register(new MinDateTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity), new DateTime(1753, 1, 1)));
                }

                //load
                pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IWrite))
                    ? ctx.ResolveNamed <IWrite>(entity.Key)
                    : new NullWriter());

                pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IUpdate))
                    ? ctx.ResolveNamed <IUpdate>(entity.Key)
                    : new NullUpdater());

                return(pipeline);
            }).Named <IPipeline>(entity.Key);
        }
Exemplo n.º 7
0
        public void ThrowsExceptionIfAnchorCannotBeFound()
        {
            var pipeline = new DefaultPipeline()
                           .OnReceive(new Step1())
                           .OnReceive(new Step2());

            var injector = new PipelineStepInjector(pipeline)
                           .OnReceive(new InjectedStep(), PipelineRelativePosition.After, typeof(Step3));

            var argumentException = Assert.Throws <ArgumentException>(() => injector.ReceivePipeline());

            Console.WriteLine(argumentException);
        }
Exemplo n.º 8
0
        public void TestNoExceptionsAreThrownWhenDecompiling(IManagedMethod method, IList <Instruction> instructions)
        {
            var pipeline = new DefaultPipeline().Without <LambdaInliningVisitor>();
            var elements = instructions.Select(i => (IElement) new InstructionElement(i)).ToList();

            Assert.DoesNotThrow(() => {
                try {
                    ApplyPipeline(pipeline, elements, method);
                }
                catch (NotSupportedException) {
                }
            });
        }
        public override void LoadEntity(ContainerBuilder builder, Process process, Entity entity)
        {
            if (process == null)
            {
                return;
            }

            var type = process.Pipeline == "defer" ? entity.Pipeline : process.Pipeline;

            builder.Register(ctx => {
                var context = ctx.ResolveNamed <IContext>(entity.Key);
                IPipeline pipeline;
                context.Debug(() => $"Registering {type} for entity {entity.Alias}.");
                var outputController = ctx.IsRegisteredWithName <IOutputController>(entity.Key) ? ctx.ResolveNamed <IOutputController>(entity.Key) : new NullOutputController();
                pipeline             = new DefaultPipeline(outputController, context);

                // TODO: rely on IInputProvider's Read method instead (after every provider has one)
                pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IRead)) ? ctx.ResolveNamed <IRead>(entity.Key) : null);
                pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IInputProvider)) ? ctx.ResolveNamed <IInputProvider>(entity.Key) : null);

                // transforms
                if (!process.ReadOnly)
                {
                    pipeline.Register(new SetSystemFields(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity)));
                }

                // pipeline.Register(new CancelTransform(context));  may create a problem when canceling without the intention to run full init afterwards
                pipeline.Register(new IncrementTransform(context));
                pipeline.Register(new DefaultTransform(context, context.GetAllEntityFields().Where(f => !f.System)));

                pipeline.Register(TransformFactory.GetTransforms(ctx, context, entity.GetAllFields().Where(f => f.Transforms.Any())));
                pipeline.Register(ValidateFactory.GetValidators(ctx, context, entity.GetAllFields().Where(f => f.Validators.Any())));

                if (!process.ReadOnly)
                {
                    pipeline.Register(new StringTruncateTransfom(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity)));
                }

                pipeline.Register(new LogTransform(context));

                // writer, TODO: rely on IOutputProvider instead
                pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IWrite)) ? ctx.ResolveNamed <IWrite>(entity.Key) : null);
                pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IOutputProvider)) ? ctx.ResolveNamed <IOutputProvider>(entity.Key) : null);

                // updater
                pipeline.Register(process.ReadOnly || !ctx.IsRegisteredWithName(entity.Key, typeof(IUpdate)) ? new NullUpdater() : ctx.ResolveNamed <IUpdate>(entity.Key));

                return(pipeline);
            }).Named <IPipeline>(entity.Key);
        }
        public static IServiceCollection WithDefaultPipeline(
            this IServiceCollection services,
            string queueName = "defaultQueue"
            )
        {
            // handler activator
            services.AddSingleton <IHandlerActivator>(provider => new DependencyInjectionHandlerActivator(provider));

            // settings, error tracker + handler, logging, serializer
            services.TryAddSingleton <SimpleRetryStrategySettings>(new SimpleRetryStrategySettings {
                MaxDeliveryAttempts       = 2,
                SecondLevelRetriesEnabled = true
            });
            services.AddSingleton <IErrorHandler, FakeErrorHandler>();
            services.AddSingleton <IErrorTracker, FakeErrorTracker>();
            services.AddSingleton <IRebusLoggerFactory, NullLoggerFactory>();
            services.AddSingleton <ISerializer, JsonSerializer>();

            // in-memory transport
            var transport = new InMemTransport(new InMemNetwork(true), queueName);

            services.AddSingleton <ITransport>(transport);

            // steps
            services.AddSingleton <IRetryStrategyStep, SimpleRetryStrategyStep>();

            // pipeline
            IPipeline PipelineFactory(IServiceProvider provider)
            {
                var pipeline = new DefaultPipeline()
                               .OnReceive(provider.GetRequiredService <IRetryStrategyStep>())
                               .OnReceive(new DeserializeIncomingMessageStep(provider.GetRequiredService <ISerializer>()))
                               .OnReceive(new ActivateHandlersStep(provider.GetRequiredService <IHandlerActivator>()))
                               .OnReceive(new DispatchIncomingMessageStep(provider.GetRequiredService <IRebusLoggerFactory>()))

                               .OnSend(new AssignDefaultHeadersStep(provider.GetRequiredService <ITransport>()))
                               .OnSend(new AutoHeadersOutgoingStep())
                               .OnSend(new SerializeOutgoingMessageStep(provider.GetRequiredService <ISerializer>()))
                               .OnSend(new SendOutgoingMessageStep(provider.GetRequiredService <ITransport>(), provider.GetRequiredService <IRebusLoggerFactory>()));

                return(pipeline);
            }

            services.AddSingleton <IPipeline>(PipelineFactory);

            // invoker
            services.AddSingleton <IPipelineInvoker>(provider => new DefaultPipelineInvoker(provider.GetRequiredService <IPipeline>()));

            return(services);
        }
        public override void LoadEntity(ContainerBuilder builder, Process process, Entity entity)
        {
            if (process == null)
            {
                return;
            }

            var type = process.Pipeline == "defer" ? entity.Pipeline : process.Pipeline;

            builder.Register(ctx => {
                var context = ctx.ResolveNamed <IContext>(entity.Key);
                context.Debug(() => string.Format("Registering {0} for entity {1}.", type, entity.Alias));
                var outputController = ctx.IsRegisteredWithName <IOutputController>(entity.Key) ? ctx.ResolveNamed <IOutputController>(entity.Key) : new NullOutputController();
                var pipeline         = new DefaultPipeline(outputController, context);

                var output = process.Output();

                // extract
                pipeline.Register(ctx.ResolveNamed <IRead>(entity.Key));

                // transform
                if (!process.ReadOnly)
                {
                    pipeline.Register(new SetSystemFields(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity, entity.TflBatchId())));
                }

                pipeline.Register(new DefaultTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity), context.GetAllEntityFields().Where(f => !f.System)));
                pipeline.Register(TransformFactory.GetTransforms(ctx, context, entity.GetAllFields().Where(f => f.Transforms.Any())));
                pipeline.Register(ValidateFactory.GetValidators(ctx, context, entity.GetAllFields().Where(f => f.Validators.Any())));

                if (!process.ReadOnly)
                {
                    pipeline.Register(new StringTruncateTransfom(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity)));
                    if (output.Provider == "sqlserver")
                    {
                        pipeline.Register(new MinDateTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity), new DateTime(1753, 1, 1)));
                    }
                }

                // writer, TODO: rely on IOutputProvider instead
                pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IWrite)) ? ctx.ResolveNamed <IWrite>(entity.Key) : null);
                pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IOutputProvider)) ? ctx.ResolveNamed <IOutputProvider>(entity.Key) : null);

                // updater
                pipeline.Register(process.ReadOnly || !ctx.IsRegisteredWithName(entity.Key, typeof(IUpdate)) ? new NullUpdater() : ctx.ResolveNamed <IUpdate>(entity.Key));

                return(pipeline);
            }).Named <IPipeline>(entity.Key);
        }
Exemplo n.º 12
0
        public void InjectsStepAtTheEndIfAnchorCannotBeFound()
        {
            var pipeline = new DefaultPipeline()
                           .OnReceive(new Step1())
                           .OnReceive(new Step2());

            var injector = new PipelineStepInjector(pipeline)
                           .OnReceive(new InjectedStep(), PipelineRelativePosition.After, typeof(Step3));

            var receivePipeline = injector.ReceivePipeline().ToArray();

            Assert.That(receivePipeline.Select(s => s.GetType()), Is.EqualTo(new[]
            {
                typeof(Step1),
                typeof(Step2),
                typeof(InjectedStep),
            }));
        }
Exemplo n.º 13
0
        public void TestAllInstructionsExceptSpecificOnesAreProcessed()
        {
            var pipeline = new DefaultPipeline().Without<LambdaInliningVisitor>();
            var disassembler = ExpressiveEngine.GetDisassembler();
            var visitor = new InstructionCollectingVisitor();

            foreach (var method in GetAllNonGenericMethods()) {
                var elements = disassembler.Disassemble(method)
                                           .Select(i => (IElement)new InstructionElement(i)).ToList();
                try { ApplyPipeline(pipeline, elements, method); } catch { continue; }
                visitor.VisitList(elements);
            }

            Assert.AreElementsEqual(
                new OpCode[0],
                visitor.OpCodes.Except(UnsupportedOpCodes).OrderBy(code => code.Name)
            );
        }
Exemplo n.º 14
0
        public void CanInjectStepInTheBack()
        {
            var pipeline = new DefaultPipeline()
                           .OnReceive(new Step1())
                           .OnReceive(new Step2());

            var injector = new PipelineStepConcatenator(pipeline)
                           .OnReceive(new InjectedStep(), PipelineAbsolutePosition.Back);

            var receivePipeline = injector.ReceivePipeline().ToArray();

            Assert.That(receivePipeline.Select(s => s.GetType()), Is.EqualTo(new[]
            {
                typeof(Step1),
                typeof(Step2),
                typeof(InjectedStep),
            }));
        }
Exemplo n.º 15
0
        public void TestAllInstructionsExceptSpecificOnesAreProcessed()
        {
            var pipeline     = new DefaultPipeline().Without <LambdaInliningVisitor>();
            var disassembler = ExpressiveEngine.GetDisassembler();
            var visitor      = new InstructionCollectingVisitor();

            foreach (var method in GetAllNonGenericMethods())
            {
                var elements = disassembler.Disassemble(method)
                               .Select(i => (IElement) new InstructionElement(i)).ToList();
                try { ApplyPipeline(pipeline, elements, method); } catch { continue; }
                visitor.VisitList(elements);
            }

            Assert.AreElementsEqual(
                new OpCode[0],
                visitor.OpCodes.Except(UnsupportedOpCodes).OrderBy(code => code.Name)
                );
        }
Exemplo n.º 16
0
        public override void LoadEntity(ContainerBuilder builder, Process process, Entity entity)
        {
            var type = process.Pipeline == "defer" ? entity.Pipeline : process.Pipeline;

            builder.Register <IPipeline>((ctx) => {
                var context = new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity);
                IPipeline pipeline;
                switch (type)
                {
                case "parallel.linq":
                    context.Debug("Registering {0} pipeline.", type);
                    pipeline = new ParallelPipeline(new DefaultPipeline(ctx.ResolveNamed <IEntityController>(entity.Key), context));
                    break;

                default:
                    context.Debug("Registering linq pipeline.", type);
                    pipeline = new DefaultPipeline(ctx.ResolveNamed <IEntityController>(entity.Key), context);
                    break;
                }

                var provider = process.Connections.First(c => c.Name == "output").Provider;

                // extract
                pipeline.Register(ctx.ResolveNamed <IRead>(entity.Key));

                // transform
                pipeline.Register(new DefaultTransform(context, context.GetAllEntityFields()));
                pipeline.Register(new TflHashCodeTransform(context));
                pipeline.Register(TransformFactory.GetTransforms(ctx, process, entity, entity.GetAllFields().Where(f => f.Transforms.Any())));
                pipeline.Register(new StringTruncateTransfom(context));

                if (provider == "sqlserver")
                {
                    pipeline.Register(new MinDateTransform(context, new DateTime(1753, 1, 1)));
                }

                //load
                pipeline.Register(ctx.ResolveNamed <IWrite>(entity.Key));
                pipeline.Register(ctx.ResolveNamed <IUpdate>(entity.Key));
                return(pipeline);
            }).Named <IPipeline>(entity.Key);
        }
Exemplo n.º 17
0
        public void CanInjectStepBeforeAnotherStep()
        {
            var pipeline = new DefaultPipeline()
                           .OnReceive(new Step1())
                           .OnReceive(new Step2())
                           .OnReceive(new Step3());

            var injector = new PipelineStepInjector(pipeline)
                           .OnReceive(new InjectedStep(), PipelineRelativePosition.Before, typeof(Step2));

            var receivePipeline = injector.ReceivePipeline().ToArray();

            Assert.That(receivePipeline.Select(s => s.GetType()), Is.EqualTo(new[]
            {
                typeof(Step1),
                typeof(InjectedStep),
                typeof(Step2),
                typeof(Step3),
            }));
        }
Exemplo n.º 18
0
    public void CheckTiming()
    {
        var pipeline = Enumerable.Range(0, 15)
                       .Select(stepNumber => new NamedStep($"step {stepNumber}"))
                       .ToArray();

        var defaultPipeline = new DefaultPipeline(initialIncomingSteps: pipeline);
        var invoker         = new DefaultPipelineInvoker(defaultPipeline);

        var stopwatch = Stopwatch.StartNew();

        1000000.Times(() =>
        {
            var stepContext = new IncomingStepContext(new TransportMessage(new Dictionary <string, string>(), new byte[0]), GetFakeTransactionContext());

            invoker.Invoke(stepContext).Wait();
        });

        Console.WriteLine($"Execution took {stopwatch.Elapsed.TotalSeconds:0.0} s");
    }
Exemplo n.º 19
0
        public override void LoadEntity(ContainerBuilder builder, Process process, Entity entity) {
            var type = process.Pipeline == "defer" ? entity.Pipeline : process.Pipeline;

            builder.Register<IPipeline>((ctx) => {
                var context = new PipelineContext(ctx.Resolve<IPipelineLogger>(), process, entity);
                IPipeline pipeline;
                switch (type) {
                    case "parallel.linq":
                        context.Debug("Registering {0} pipeline.", type);
                        pipeline = new ParallelPipeline(new DefaultPipeline(ctx.ResolveNamed<IEntityController>(entity.Key), context));
                        break;
                    default:
                        context.Debug("Registering linq pipeline.", type);
                        pipeline = new DefaultPipeline(ctx.ResolveNamed<IEntityController>(entity.Key), context);
                        break;
                }

                var provider = process.Connections.First(c => c.Name == "output").Provider;

                // extract
                pipeline.Register(ctx.ResolveNamed<IRead>(entity.Key));

                // transform
                pipeline.Register(new DefaultTransform(context, context.GetAllEntityFields()));
                pipeline.Register(new TflHashCodeTransform(context));
                pipeline.Register(TransformFactory.GetTransforms(ctx,process, entity, entity.GetAllFields().Where(f=>f.Transforms.Any())));
                pipeline.Register(new StringTruncateTransfom(context));

                if (provider == "sqlserver") {
                    pipeline.Register(new MinDateTransform(context, new DateTime(1753, 1, 1)));
                }

                //load
                pipeline.Register(ctx.ResolveNamed<IWrite>(entity.Key));
                pipeline.Register(ctx.ResolveNamed<IUpdate>(entity.Key));
                return pipeline;

            }).Named<IPipeline>(entity.Key);
        }
        public void Execute()
        {
            var pipeline = new DefaultPipeline <WebServicePublisherContext>(
                Load <GetQueuedMessagesStep>(),
                Load <SendMessagesStep>(),
                Load <CleanupMessagesStep>());

            var result = pipeline.Execute(new WebServicePublisherContext());

            if (result.Success)
            {
                return;
            }

            var ex = result.StepResults.FirstOrDefault(sr => sr.Failure != null);

            if (ex != null)
            {
                throw new ApplicationException("Step failure", ex.Failure.Error);
            }

            throw new ApplicationException("Pipeline failure");
        }
Exemplo n.º 21
0
 public void Dispose()
 {
     DefaultPipeline.Dispose();
 }
Exemplo n.º 22
0
        protected override void Load(ContainerBuilder builder)
        {
            if (_process == null)
            {
                return;
            }

            var calc   = _process.ToCalculatedFieldsProcess();
            var entity = calc.Entities.First();

            // I need a process keyed pipeline
            builder.Register(ctx => {
                var context       = new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity);
                var outputContext = new OutputContext(context, new Incrementer(context));

                IPipeline pipeline;
                context.Debug(() => $"Registering {_process.Pipeline} pipeline.");
                var outputController = ctx.IsRegistered <IOutputController>() ? ctx.Resolve <IOutputController>() : new NullOutputController();
                switch (_process.Pipeline)
                {
                case "parallel.linq":
                    pipeline = new ParallelPipeline(new DefaultPipeline(outputController, context));
                    break;

                default:
                    pipeline = new DefaultPipeline(outputController, context);
                    break;
                }

                // no updater necessary
                pipeline.Register(new NullUpdater(context, false));

                if (!_process.CalculatedFields.Any())
                {
                    pipeline.Register(new NullReader(context, false));
                    pipeline.Register(new NullWriter(context, false));
                    return(pipeline);
                }

                // register transforms
                pipeline.Register(new DefaultTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity), entity.CalculatedFields));
                pipeline.Register(TransformFactory.GetTransforms(ctx, calc, entity, entity.CalculatedFields));
                pipeline.Register(new StringTruncateTransfom(new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity)));

                // register input and output
                switch (outputContext.Connection.Provider)
                {
                case "sqlserver":
                    pipeline.Register(ctx.Resolve <IRead>());
                    pipeline.Register(ctx.Resolve <IWrite>());
                    pipeline.Register(new MinDateTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity), new DateTime(1753, 1, 1)));
                    break;

                case "mysql":
                case "postgresql":
                case "sqlce":
                case "sqlite":
                    pipeline.Register(ctx.Resolve <IRead>());
                    pipeline.Register(ctx.Resolve <IWrite>());
                    break;

                default:
                    pipeline.Register(new NullReader(context));
                    pipeline.Register(new NullWriter(context));
                    break;
                }

                return(pipeline);
            }).As <IPipeline>();
        }
Exemplo n.º 23
0
 public PipelineBuilder()
 {
     _pipeline = new DefaultPipeline <TIn, TOut>();
 }
Exemplo n.º 24
0
        public ILifetimeScope CreateScope(Process process, IPipelineLogger logger)
        {
            var builder = new ContainerBuilder();

            // the modules below rely on this process being there
            builder.Properties["Process"] = process;

            builder.Register(ctx => process).As <Process>();
            builder.RegisterInstance(logger).As <IPipelineLogger>().SingleInstance();

            // register short-hand for t attribute, allowing for additional transforms
            var tm = new TransformModule(process, _methods, _shortHand, logger)
            {
                Plugins = false
            };

            // adding additional transforms here
            tm.AddTransform(new TransformHolder((c) => new UsernameTransform(_httpContext, c), new UsernameTransform().GetSignatures()));
            tm.AddTransform(new TransformHolder((c) => new UserIdTransform(_httpContext, _userService, c), new UserIdTransform().GetSignatures()));
            tm.AddTransform(new TransformHolder((c) => new UserEmailTransform(_httpContext, _userService, c), new UserEmailTransform().GetSignatures()));
            tm.AddTransform(new TransformHolder((c) => new OrchardRazorTransform(c, _memoryCache, _signal), new OrchardRazorTransform().GetSignatures()));
            tm.AddTransform(new TransformHolder((c) => new OrchardFluidTransform(c, _memoryCache, _signal), new OrchardFluidTransform().GetSignatures()));
            tm.AddTransform(new TransformHolder((c) => new OrchardJintTransform(c, new DefaultReader(new FileReader(), new WebReader()), _memoryCache, _signal), new OrchardJintTransform().GetSignatures()));
            tm.AddTransform(new TransformHolder((c) => new ToLocalTimeTransform(c, _clock, _localClock), new ToLocalTimeTransform().GetSignatures()));
            tm.AddTransform(new TransformHolder((c) => new GetEncodedUrlTransform(_httpContext, c), new GetEncodedUrlTransform().GetSignatures()));
            tm.AddTransform(new TransformHolder((c) => new GetDisplayUrlTransform(_httpContext, c), new GetDisplayUrlTransform().GetSignatures()));
            tm.AddTransform(new TransformHolder((c) => new OrchardTimeZoneTransform(c), new OrchardTimeZoneTransform().GetSignatures()));
            tm.AddTransform(new TransformHolder((c) => new GeocodeTransform(c), new GeocodeTransform().GetSignatures()));
            tm.AddTransform(new TransformHolder((c) => new PlaceTransform(c), new PlaceTransform().GetSignatures()));
            tm.AddTransform(new TransformHolder((c) => new FilePartTransform(c, _fileService), new FilePartTransform().GetSignatures()));

            builder.RegisterModule(tm);

            // register short-hand for v attribute, allowing for additional validators
            var vm = new ValidateModule(process, _methods, _shortHand, logger)
            {
                Plugins = false
            };

            // adding additional validators here
            builder.RegisterModule(vm);

            // using custom internal module that does not handle the nested transformalize actions
            builder.RegisterModule(new OrchardInternalModule(process));

            // handling nested transformalize actions here instead
            foreach (var action in process.Actions.Where(a => a.GetModes().Any(m => m == process.Mode || m == "*")))
            {
                if (action.Type == "tfl")
                {
                    builder.Register <IAction>(ctx => {
                        return(new PipelineAction(action, _serviceProvider));
                    }).Named <IAction>(action.Key);
                }
            }

            // register providers
            var providers = new HashSet <string>(process.Connections.Select(c => c.Provider));

            // relational databases
            builder.RegisterModule(new AdoProviderModule());
            if (providers.Contains("sqlserver"))
            {
                builder.RegisterModule(new SqlServerModule()
                {
                    ConnectionFactory = (c) => new ProfiledConnectionFactory(new SqlServerConnectionFactory(c))
                });
            }
            if (providers.Contains("postgresql"))
            {
                builder.RegisterModule(new PostgreSqlModule()
                {
                    ConnectionFactory = (c) => new ProfiledConnectionFactory(new PostgreSqlConnectionFactory(c))
                });
            }
            if (providers.Contains("sqlite"))
            {
                builder.RegisterModule(new SqliteModule()
                {
                    ConnectionFactory = (c) => new ProfiledConnectionFactory(new SqliteConnectionFactory(c))
                });
            }
            if (providers.Contains("mysql"))
            {
                builder.RegisterModule(new MySqlModule()
                {
                    ConnectionFactory = (c) => new ProfiledConnectionFactory(new MySqlConnectionFactory(c))
                });
            }

            // search engines
            if (providers.Contains("elasticsearch"))
            {
                builder.RegisterModule(new ElasticsearchModule());
            }
            // solr
            // lucene

            // importing, exporting
            var stream = _httpContext.HttpContext.Response.Body;

            if (providers.Contains("file"))
            {
                builder.RegisterModule(new CsvHelperProviderModule(stream));
            }
            if (providers.Contains("excel"))
            {
                builder.RegisterModule(new OrchardExcelModule());
            }

            // exporting
            if (providers.Contains("json"))
            {
                builder.RegisterModule(new JsonProviderModule(stream)
                {
                    UseAsyncMethods = true
                });
            }
            if (providers.Contains("geojson"))
            {
                builder.RegisterModule(new GeoJsonProviderModule(stream)
                {
                    UseAsyncMethods = true
                });
            }

            // misc
            if (providers.Contains("bogus"))
            {
                builder.RegisterModule(new BogusModule());
            }
            if (providers.Contains("log") || process.Actions.Any(a => a.Type == "log"))
            {
                builder.RegisterModule(new OrchardLogModule(process));
            }
            if (providers.Contains("mail"))
            {
                builder.RegisterModule(new MailModule());
            }
            if (providers.Contains("aws"))
            {
                var services = new HashSet <string>(process.Connections.Where(c => c.Provider == "aws").Select(c => c.Service));
                if (services.Contains("logs"))
                {
                    builder.RegisterModule(new AwsCloudWatchProviderModule());
                }
                if (services.Contains("connect"))
                {
                    builder.RegisterModule(new AmazonConnectProviderModule());
                }
            }

            // transform and validation modules need these properties
            builder.Properties["ShortHand"] = _shortHand;
            builder.Properties["Methods"]   = _methods;

            // register transform modules here
            builder.RegisterModule(new JsonTransformModule());
            builder.RegisterModule(new HumanizeModule());
            builder.RegisterModule(new FileModule());
            builder.RegisterModule(new AdoTransformModule());
            builder.RegisterModule(new LambdaParserModule());
            builder.RegisterModule(new AwsTransformModule());

            // register validator modules here
            builder.RegisterModule(new JintValidateModule());

            // process context
            builder.Register <IContext>((ctx, p) => new PipelineContext(logger, process)).As <IContext>();

            // process output context
            builder.Register(ctx => {
                var context = ctx.Resolve <IContext>();
                return(new OutputContext(context));
            }).As <OutputContext>();

            // connection and process level output context
            var formWriter = false;

            foreach (var connection in process.Connections)
            {
                builder.Register(ctx => new ConnectionContext(ctx.Resolve <IContext>(), connection)).Named <IConnectionContext>(connection.Key);

                // there can only be one form writer
                if (!formWriter && connection.Table != "[default]" && connection.Provider != "[default]")
                {
                    builder.Register(ctx => {
                        var context           = ctx.ResolveNamed <IConnectionContext>(connection.Key);
                        var connectionFactory = ctx.ResolveNamed <IConnectionFactory>(connection.Key);
                        return(new AdoFormCommandWriter(context, connectionFactory));
                    }).As <AdoFormCommandWriter>();
                    formWriter = true;
                }

                if (connection.Name != process.Output)
                {
                    continue;
                }

                // register output for connection
                builder.Register(ctx => {
                    var context = ctx.ResolveNamed <IConnectionContext>(connection.Key);
                    return(new OutputContext(context));
                }).Named <OutputContext>(connection.Key);
            }

            // entity context and rowFactory
            foreach (var entity in process.Entities)
            {
                builder.Register <IContext>((ctx, p) => new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity)).Named <IContext>(entity.Key);

                builder.Register(ctx => {
                    var context = ctx.ResolveNamed <IContext>(entity.Key);
                    return(new InputContext(context));
                }).Named <InputContext>(entity.Key);

                builder.Register <IRowFactory>((ctx, p) => new RowFactory(p.Named <int>("capacity"), entity.IsMaster, false)).Named <IRowFactory>(entity.Key);

                builder.Register(ctx => {
                    var context = ctx.ResolveNamed <IContext>(entity.Key);
                    return(new OutputContext(context));
                }).Named <OutputContext>(entity.Key);

                var connection = process.Connections.First(c => c.Name == entity.Input);
                builder.Register(ctx => new ConnectionContext(ctx.Resolve <IContext>(), connection)).Named <IConnectionContext>(entity.Key);
            }

            // entity pipelines
            foreach (var entity in process.Entities)
            {
                builder.Register(ctx => {
                    var output           = process.GetOutputConnection();
                    var context          = ctx.ResolveNamed <IContext>(entity.Key);
                    var outputController = ctx.IsRegisteredWithName <IOutputController>(entity.Key) ? ctx.ResolveNamed <IOutputController>(entity.Key) : new NullOutputController();
                    var pipeline         = new DefaultPipeline(outputController, context);

                    if (entity.IsMaster)
                    {
                        if (GetReaderAlternate != null)
                        {
                            // Using an alternate reader (e.g. a ParameterRowReader that reads parameters into a row)
                            var input      = ctx.ResolveNamed <InputContext>(entity.Key);
                            var rowFactory = ctx.ResolveNamed <IRowFactory>(entity.Key, new NamedParameter("capacity", input.RowCapacity));
                            pipeline.Register(GetReaderAlternate(input, rowFactory));
                        }
                        else if (GetReaderDecorator != null && ctx.IsRegisteredWithName(entity.Key, typeof(IRead)))
                        {
                            // Decorating the normally registered reader (e.g. ParameterRowReader updating a row from an AdoReader)
                            // TODO: Support IInputProvider instead of just IRead
                            var input      = ctx.ResolveNamed <InputContext>(entity.Key);
                            var rowFactory = ctx.ResolveNamed <IRowFactory>(entity.Key, new NamedParameter("capacity", input.RowCapacity));
                            pipeline.Register(GetReaderDecorator(ctx.ResolveNamed <IRead>(entity.Key), input, rowFactory));
                        }
                        else
                        {
                            pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IRead)) ? ctx.ResolveNamed <IRead>(entity.Key) : null);
                            pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IInputProvider)) ? ctx.ResolveNamed <IInputProvider>(entity.Key) : null);
                        }
                    }
                    else
                    {
                        // TODO: rely on IInputProvider's Read method instead (after every provider has one)
                        pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IRead)) ? ctx.ResolveNamed <IRead>(entity.Key) : null);
                        pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IInputProvider)) ? ctx.ResolveNamed <IInputProvider>(entity.Key) : null);
                    }

                    // transforms
                    if (!process.ReadOnly)
                    {
                        pipeline.Register(new SetSystemFields(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity)));
                    }

                    pipeline.Register(new IncrementTransform(context));
                    pipeline.Register(new DefaultTransform(context, context.GetAllEntityFields().Where(f => !f.System)));
                    pipeline.Register(TransformFactory.GetTransforms(ctx, context, entity.GetAllFields().Where(f => f.Transforms.Any())));
                    pipeline.Register(ValidateFactory.GetValidators(ctx, context, entity.GetAllFields().Where(f => f.Validators.Any())));

                    if (!process.ReadOnly && !output.Provider.In("internal", "log"))
                    {
                        pipeline.Register(new StringTruncateTransfom(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity)));
                    }

                    pipeline.Register(new LogTransform(context));

                    // writer, TODO: rely on IOutputProvider instead
                    pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IWrite)) ? ctx.ResolveNamed <IWrite>(entity.Key) : null);
                    pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IOutputProvider)) ? ctx.ResolveNamed <IOutputProvider>(entity.Key) : null);

                    // updater
                    pipeline.Register(process.ReadOnly || !ctx.IsRegisteredWithName(entity.Key, typeof(IUpdate)) ? new NullUpdater() : ctx.ResolveNamed <IUpdate>(entity.Key));

                    return(pipeline);
                }).Named <IPipeline>(entity.Key);
            }

            if (process.Entities.Count > 1 && process.Relationships.Any())
            {
                // process pipeline
                builder.Register(ctx => {
                    var calc   = process.ToCalculatedFieldsProcess();
                    var entity = calc.Entities.First();

                    var context       = new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity);
                    var outputContext = new OutputContext(context);

                    context.Debug(() => $"Registering {process.Pipeline} pipeline.");
                    var outputController = ctx.IsRegistered <IOutputController>() ? ctx.Resolve <IOutputController>() : new NullOutputController();
                    var pipeline         = new DefaultPipeline(outputController, context);

                    // no updater necessary
                    pipeline.Register(new NullUpdater(context, false));

                    if (!process.CalculatedFields.Any())
                    {
                        pipeline.Register(new NullReader(context, false));
                        pipeline.Register(new NullWriter(context, false));
                        return(pipeline);
                    }

                    // register transforms
                    pipeline.Register(new IncrementTransform(context));
                    pipeline.Register(new LogTransform(context));
                    pipeline.Register(new DefaultTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity), entity.CalculatedFields));

                    pipeline.Register(TransformFactory.GetTransforms(ctx, context, entity.CalculatedFields));
                    pipeline.Register(ValidateFactory.GetValidators(ctx, context, entity.GetAllFields().Where(f => f.Validators.Any())));

                    pipeline.Register(new StringTruncateTransfom(new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity)));

                    // register input and output
                    pipeline.Register(ctx.IsRegistered <IRead>() ? ctx.Resolve <IRead>() : new NullReader(context));
                    pipeline.Register(ctx.IsRegistered <IWrite>() ? ctx.Resolve <IWrite>() : new NullWriter(context));

                    if (outputContext.Connection.Provider == "sqlserver")
                    {
                        pipeline.Register(new MinDateTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity), new DateTime(1753, 1, 1)));
                    }

                    return(pipeline);
                }).As <IPipeline>();
            }

            // process controller
            builder.Register <IProcessController>(ctx => {
                var pipelines = new List <IPipeline>();

                // entity-level pipelines
                foreach (var entity in process.Entities)
                {
                    var pipeline = ctx.ResolveNamed <IPipeline>(entity.Key);

                    pipelines.Add(pipeline);
                    if (entity.Delete && process.Mode != "init")
                    {
                        pipeline.Register(ctx.ResolveNamed <IEntityDeleteHandler>(entity.Key));
                    }
                }

                // process-level pipeline for process level calculated fields
                if (ctx.IsRegistered <IPipeline>())
                {
                    pipelines.Add(ctx.Resolve <IPipeline>());
                }

                var context    = ctx.Resolve <IContext>();
                var controller = new ProcessController(pipelines, context);

                // output initialization
                if (process.Mode == "init" && ctx.IsRegistered <IInitializer>())
                {
                    controller.PreActions.Add(ctx.Resolve <IInitializer>());
                }

                // flatten(ing) is first post-action
                var output = process.GetOutputConnection();
                var isAdo  = _adoProviders.Contains(output.Provider);
                if (process.Flatten && isAdo)
                {
                    if (ctx.IsRegisteredWithName <IAction>(output.Key))
                    {
                        controller.PostActions.Add(ctx.ResolveNamed <IAction>(output.Key));
                    }
                    else
                    {
                        context.Error($"Could not find ADO Flatten Action for provider {output.Provider}.");
                    }
                }

                // actions
                foreach (var action in process.Actions.Where(a => a.GetModes().Any(m => m == process.Mode || m == "*")))
                {
                    if (ctx.IsRegisteredWithName <IAction>(action.Key))
                    {
                        if (action.Before)
                        {
                            controller.PreActions.Add(ctx.ResolveNamed <IAction>(action.Key));
                        }
                        if (action.After)
                        {
                            controller.PostActions.Add(ctx.ResolveNamed <IAction>(action.Key));
                        }
                    }
                    else
                    {
                        if (action.Type != "internal")
                        {
                            _logger.Warn(() => $"The action {action.Name} with type {action.Type} isn't registered.");
                        }
                    }
                }

                foreach (var map in process.Maps.Where(m => !string.IsNullOrEmpty(m.Query)))
                {
                    controller.PreActions.Add(new MapReaderAction(context, map, ctx.ResolveNamed <IMapReader>(map.Name)));
                }

                return(controller);
            }).As <IProcessController>();

            var build = builder.Build();

            return(build.BeginLifetimeScope());
        }
Exemplo n.º 25
0
        protected override void RegisterProcess(ContainerBuilder builder, Process original)
        {
            // I need to create a new process with an entity with the appropriate fields

            // clone process, remove entities, and create entity needed for calcuted fields
            var calc = original.Clone() as Process;

            calc.Entities.Clear();
            calc.CalculatedFields.Clear();
            calc.Relationships.Clear();

            var entity = original.GetDefaultOf <Entity>(e => {
                e.Name       = "sys.Calc";
                e.Connection = "output";
                e.IsMaster   = false;
                e.Fields     = new List <Field> {
                    original.GetDefaultOf <Field>(f => {
                        f.Name       = Constants.TflKey;
                        f.Type       = "int";
                        f.PrimaryKey = true;
                    })
                };
            });

            // Add fields that calculated fields depend on
            entity.Fields.AddRange(original.CalculatedFields
                                   .SelectMany(f => f.Transforms)
                                   .SelectMany(t => t.Parameters)
                                   .Where(p => !p.HasValue() && p.IsField(original))
                                   .Select(p => p.AsField(original).Clone() as Field)
                                   );

            entity.CalculatedFields.AddRange(original.CalculatedFields.Select(cf => cf.Clone() as Field));

            calc.Entities.Add(entity);
            calc.ModifyKeys();
            calc.ModifyIndexes();

            // I need a process keyed pipeline
            builder.Register((ctx) => {
                var context = new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity);
                IPipeline pipeline;
                switch (original.Pipeline)
                {
                case "parallel.linq":
                    context.Debug("Registering {0} pipeline.", original.Pipeline);
                    pipeline = new ParallelPipeline(new DefaultPipeline(new NullEntityController(), context));
                    break;

                default:
                    context.Debug("Registering linq pipeline.", original.Pipeline);
                    pipeline = new DefaultPipeline(new NullEntityController(), context);
                    break;
                }

                // register transforms
                pipeline.Register(new DefaultTransform(context, entity.CalculatedFields));
                pipeline.Register(TransformFactory.GetTransforms(ctx, calc, entity, entity.CalculatedFields));
                pipeline.Register(new StringTruncateTransfom(context));

                // register input and output
                var outputContext = new OutputContext(context, new Incrementer(context));
                switch (outputContext.Connection.Provider)
                {
                case "sqlserver":
                    pipeline.Register(new SqlStarParametersReader(outputContext, original));
                    pipeline.Register(new SqlCalculatedFieldUpdater(outputContext, original));
                    pipeline.Register(new MinDateTransform(context, new DateTime(1753, 1, 1)));
                    break;

                default:
                    pipeline.Register(new NullReader(context));
                    pipeline.Register(new NullWriter(context));
                    break;
                }

                // no updater necessary
                pipeline.Register(new NullUpdater(context, false));

                return(pipeline);
            }).Named <IPipeline>(original.Key);
        }
Exemplo n.º 26
0
        public override void LoadEntity(ContainerBuilder builder, Process process, Entity entity)
        {
            if (process == null)
            {
                return;
            }

            var type = process.Pipeline == "defer" ? entity.Pipeline : process.Pipeline;

            builder.Register(ctx => {
                var context = ctx.ResolveNamed <IContext>(entity.Key);
                IPipeline pipeline;
                context.Debug(() => $"Registering {type} for entity {entity.Alias}.");
                var outputController = ctx.IsRegisteredWithName <IOutputController>(entity.Key) ? ctx.ResolveNamed <IOutputController>(entity.Key) : new NullOutputController();
                switch (type)
                {
                case "parallel.linq":
                    pipeline = new ParallelPipeline(new DefaultPipeline(outputController, context));
                    break;

                default:
                    pipeline = new DefaultPipeline(outputController, context);
                    break;
                }

                var output = process.Output();

                // TODO: rely on IInputProvider's Read method instead (after every provider has one)
                pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IRead)) ? ctx.ResolveNamed <IRead>(entity.Key) : null);
                pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IInputProvider)) ? ctx.ResolveNamed <IInputProvider>(entity.Key) : null);

                // transforms
                if (!process.ReadOnly)
                {
                    pipeline.Register(new SetSystemFields(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity)));
                }

                pipeline.Register(new CancelTransform(context));
                pipeline.Register(new IncrementTransform(context));
                pipeline.Register(new DefaultTransform(context, context.GetAllEntityFields().Where(f => !f.System)));

                if (ctx.ResolveNamed <IConnectionContext>(entity.Key).Connection.Provider.In("internal", "file", Constants.DefaultSetting))
                {
                    foreach (var field in entity.Fields.Where(f => f.Input && f.Type != "string" && (!f.Transforms.Any() || f.Transforms.First().Method != "convert")))
                    {
                        context.Debug(() => "Automatically adding convert transform");
                        pipeline.Register(new ConvertTransform(new PipelineContext(context.Logger, context.Process, entity, field, new Operation {
                            Method = "convert"
                        })));
                    }
                }

                pipeline.Register(TransformFactory.GetTransforms(ctx, context, entity.GetAllFields().Where(f => f.Transforms.Any())));
                pipeline.Register(ValidateFactory.GetValidators(ctx, context, entity.GetAllFields().Where(f => f.Validators.Any())));

                if (!process.ReadOnly)
                {
                    pipeline.Register(new StringTruncateTransfom(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity)));
                    if (output.Provider == "sqlserver")
                    {
                        pipeline.Register(new MinDateTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity), new DateTime(1753, 1, 1)));
                    }
                }

                pipeline.Register(new LogTransform(context));

                // writer, TODO: rely on IOutputProvider instead
                pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IWrite)) ? ctx.ResolveNamed <IWrite>(entity.Key) : null);
                pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IOutputProvider)) ? ctx.ResolveNamed <IOutputProvider>(entity.Key) : null);

                // updater
                pipeline.Register(process.ReadOnly || !ctx.IsRegisteredWithName(entity.Key, typeof(IUpdate)) ? new NullUpdater() : ctx.ResolveNamed <IUpdate>(entity.Key));

                return(pipeline);
            }).Named <IPipeline>(entity.Key);
        }
Exemplo n.º 27
0
        protected override void RegisterProcess(ContainerBuilder builder, Process original) {

            // I need to create a new process with an entity with the appropriate fields

            // clone process, remove entities, and create entity needed for calcuted fields
            var calc = original.Clone() as Process;
            calc.Entities.Clear();
            calc.CalculatedFields.Clear();
            calc.Relationships.Clear();

            var entity = original.GetDefaultOf<Entity>(e => {
                e.Name = "sys.Calc";
                e.Connection = "output";
                e.IsMaster = false;
                e.Fields = new List<Field> {
                    original.GetDefaultOf<Field>(f => {
                        f.Name = Constants.TflKey;
                        f.Type = "int";
                        f.PrimaryKey = true;
                    })
                };
            });

            // Add fields that calculated fields depend on
            entity.Fields.AddRange(original.CalculatedFields
                .SelectMany(f => f.Transforms)
                .SelectMany(t => t.Parameters)
                .Where(p => !p.HasValue() && p.IsField(original))
                .Select(p => p.AsField(original).Clone() as Field)
                );

            entity.CalculatedFields.AddRange(original.CalculatedFields.Select(cf => cf.Clone() as Field));

            calc.Entities.Add(entity);
            calc.ModifyKeys();
            calc.ModifyIndexes();

            // I need a process keyed pipeline
            builder.Register((ctx) => {
                var context = new PipelineContext(ctx.Resolve<IPipelineLogger>(), calc, entity);
                IPipeline pipeline;
                switch (original.Pipeline) {
                    case "parallel.linq":
                        context.Debug("Registering {0} pipeline.", original.Pipeline);
                        pipeline = new ParallelPipeline(new DefaultPipeline(new NullEntityController(), context));
                        break;
                    default:
                        context.Debug("Registering linq pipeline.", original.Pipeline);
                        pipeline = new DefaultPipeline(new NullEntityController(), context);
                        break;
                }

                // register transforms
                pipeline.Register(new DefaultTransform(context, entity.CalculatedFields));
                pipeline.Register(TransformFactory.GetTransforms(ctx, calc, entity, entity.CalculatedFields));
                pipeline.Register(new StringTruncateTransfom(context));

                // register input and output
                var outputContext = new OutputContext(context, new Incrementer(context));
                switch (outputContext.Connection.Provider) {
                    case "sqlserver":
                        pipeline.Register(new SqlStarParametersReader(outputContext, original));
                        pipeline.Register(new SqlCalculatedFieldUpdater(outputContext, original));
                        pipeline.Register(new MinDateTransform(context, new DateTime(1753, 1, 1)));
                        break;
                    default:
                        pipeline.Register(new NullReader(context));
                        pipeline.Register(new NullWriter(context));
                        break;
                }

                // no updater necessary
                pipeline.Register(new NullUpdater(context, false));

                return pipeline;
            }).Named<IPipeline>(original.Key);

        }
Exemplo n.º 28
0
        public ILifetimeScope CreateScope(Process process, IPipelineLogger logger)
        {
            var builder = new ContainerBuilder();

#if PLUGINS
            builder.Properties["Process"] = process;
#endif
            builder.Register(ctx => process).As <Process>();
            builder.RegisterInstance(logger).As <IPipelineLogger>().SingleInstance();

            // register short-hand for t attribute, allowing for additional transforms
            var transformModule = new TransformModule(process, _methods, _shortHand, logger);
            foreach (var t in _transforms)
            {
                transformModule.AddTransform(t);
            }
            builder.RegisterModule(transformModule);

            // register short-hand for v attribute, allowing for additional validators
            var validateModule = new ValidateModule(process, _methods, _shortHand, logger);
            foreach (var v in _validators)
            {
                validateModule.AddValidator(v);
            }
            builder.RegisterModule(validateModule);

            builder.RegisterModule(new InternalModule(process));

#if PLUGINS
            // just in case other modules need to see these
            builder.Properties["ShortHand"] = _shortHand;
            builder.Properties["Methods"]   = _methods;
#endif

            // allowing for additional modules
            foreach (var module in _modules)
            {
                builder.RegisterModule(module);
            }

            // Process Context
            builder.Register <IContext>((ctx, p) => new PipelineContext(logger, process)).As <IContext>();

            // Process Output Context
            builder.Register(ctx => {
                var context = ctx.Resolve <IContext>();
                return(new OutputContext(context));
            }).As <OutputContext>();

            // Connection and Process Level Output Context
            foreach (var connection in process.Connections)
            {
                builder.Register(ctx => new ConnectionContext(ctx.Resolve <IContext>(), connection)).Named <IConnectionContext>(connection.Key);

                if (connection.Name != "output")
                {
                    continue;
                }

                // register output for connection
                builder.Register(ctx => {
                    var context = ctx.ResolveNamed <IConnectionContext>(connection.Key);
                    return(new OutputContext(context));
                }).Named <OutputContext>(connection.Key);
            }

            // Entity Context and RowFactory
            foreach (var entity in process.Entities)
            {
                builder.Register <IContext>((ctx, p) => new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity)).Named <IContext>(entity.Key);

                builder.Register(ctx => {
                    var context = ctx.ResolveNamed <IContext>(entity.Key);
                    return(new InputContext(context));
                }).Named <InputContext>(entity.Key);

                builder.Register <IRowFactory>((ctx, p) => new RowFactory(p.Named <int>("capacity"), entity.IsMaster, false)).Named <IRowFactory>(entity.Key);

                builder.Register(ctx => {
                    var context = ctx.ResolveNamed <IContext>(entity.Key);
                    return(new OutputContext(context));
                }).Named <OutputContext>(entity.Key);

                var connection = process.Connections.First(c => c.Name == entity.Connection);
                builder.Register(ctx => new ConnectionContext(ctx.Resolve <IContext>(), connection)).Named <IConnectionContext>(entity.Key);
            }

            // entity pipelines
            foreach (var entity in process.Entities)
            {
                builder.Register(ctx => {
                    var type = process.Pipeline == "defer" ? entity.Pipeline : process.Pipeline;

                    var context = ctx.ResolveNamed <IContext>(entity.Key);
                    context.Debug(() => $"Registering {type} for entity {entity.Alias}.");
                    var outputController = ctx.IsRegisteredWithName <IOutputController>(entity.Key) ? ctx.ResolveNamed <IOutputController>(entity.Key) : new NullOutputController();
                    var pipeline         = new DefaultPipeline(outputController, context);

                    // TODO: rely on IInputProvider's Read method instead (after every provider has one)
                    pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IRead)) ? ctx.ResolveNamed <IRead>(entity.Key) : null);
                    pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IInputProvider)) ? ctx.ResolveNamed <IInputProvider>(entity.Key) : null);

                    // transforms
                    if (!process.ReadOnly)
                    {
                        pipeline.Register(new SetSystemFields(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity)));
                    }

                    pipeline.Register(new IncrementTransform(context));
                    pipeline.Register(new DefaultTransform(context, context.GetAllEntityFields().Where(f => !f.System)));
                    pipeline.Register(TransformFactory.GetTransforms(ctx, context, entity.GetAllFields().Where(f => f.Transforms.Any())));
                    pipeline.Register(ValidateFactory.GetValidators(ctx, context, entity.GetAllFields().Where(f => f.Validators.Any())));

                    if (!process.ReadOnly)
                    {
                        pipeline.Register(new StringTruncateTransfom(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity)));
                    }

                    pipeline.Register(new LogTransform(context));

                    // writer, TODO: rely on IOutputProvider instead
                    pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IWrite)) ? ctx.ResolveNamed <IWrite>(entity.Key) : null);
                    pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IOutputProvider)) ? ctx.ResolveNamed <IOutputProvider>(entity.Key) : null);

                    // updater
                    pipeline.Register(process.ReadOnly || !ctx.IsRegisteredWithName(entity.Key, typeof(IUpdate)) ? new NullUpdater() : ctx.ResolveNamed <IUpdate>(entity.Key));

                    return(pipeline);
                }).Named <IPipeline>(entity.Key);
            }


            // process pipeline
            builder.Register(ctx => {
                var calc   = process.ToCalculatedFieldsProcess();
                var entity = calc.Entities.First();

                var context       = new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity);
                var outputContext = new OutputContext(context);

                context.Debug(() => $"Registering {process.Pipeline} pipeline.");
                var outputController = ctx.IsRegistered <IOutputController>() ? ctx.Resolve <IOutputController>() : new NullOutputController();
                var pipeline         = new DefaultPipeline(outputController, context);

                // no updater necessary
                pipeline.Register(new NullUpdater(context, false));

                if (!process.CalculatedFields.Any())
                {
                    pipeline.Register(new NullReader(context, false));
                    pipeline.Register(new NullWriter(context, false));
                    return(pipeline);
                }

                // register transforms
                pipeline.Register(new IncrementTransform(context));
                pipeline.Register(new LogTransform(context));
                pipeline.Register(new DefaultTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity), entity.CalculatedFields));

                pipeline.Register(TransformFactory.GetTransforms(ctx, context, entity.CalculatedFields));
                pipeline.Register(ValidateFactory.GetValidators(ctx, context, entity.GetAllFields().Where(f => f.Validators.Any())));

                pipeline.Register(new StringTruncateTransfom(new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity)));

                // register input and output
                pipeline.Register(ctx.IsRegistered <IRead>() ? ctx.Resolve <IRead>() : new NullReader(context));
                pipeline.Register(ctx.IsRegistered <IWrite>() ? ctx.Resolve <IWrite>() : new NullWriter(context));

                if (outputContext.Connection.Provider == "sqlserver")
                {
                    pipeline.Register(new MinDateTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity), new DateTime(1753, 1, 1)));
                }

                return(pipeline);
            }).As <IPipeline>();

            // process controller
            builder.Register <IProcessController>(ctx => {
                var pipelines = new List <IPipeline>();

                // entity-level pipelines
                foreach (var entity in process.Entities)
                {
                    var pipeline = ctx.ResolveNamed <IPipeline>(entity.Key);

                    pipelines.Add(pipeline);
                    if (entity.Delete && process.Mode != "init")
                    {
                        pipeline.Register(ctx.ResolveNamed <IEntityDeleteHandler>(entity.Key));
                    }
                }

                // process-level pipeline for process level calculated fields
                if (ctx.IsRegistered <IPipeline>())
                {
                    pipelines.Add(ctx.Resolve <IPipeline>());
                }

                var context    = ctx.Resolve <IContext>();
                var controller = new ProcessController(pipelines, context);

                // output initialization
                if (process.Mode == "init" && ctx.IsRegistered <IInitializer>())
                {
                    controller.PreActions.Add(ctx.Resolve <IInitializer>());
                }

                // flatten(ing) is first post-action
                var isAdo = Constants.AdoProviderSet().Contains(process.Output().Provider);
                if (process.Flatten && isAdo)
                {
                    if (ctx.IsRegisteredWithName <IAction>(process.Output().Key))
                    {
                        controller.PostActions.Add(ctx.ResolveNamed <IAction>(process.Output().Key));
                    }
                    else
                    {
                        context.Error($"Could not find ADO Flatten Action for provider {process.Output().Provider}.");
                    }
                }

                // actions
                foreach (var action in process.Actions.Where(a => a.GetModes().Any(m => m == process.Mode || m == "*")))
                {
                    if (action.Before)
                    {
                        controller.PreActions.Add(ctx.ResolveNamed <IAction>(action.Key));
                    }
                    if (action.After)
                    {
                        controller.PostActions.Add(ctx.ResolveNamed <IAction>(action.Key));
                    }
                }

                return(controller);
            }).As <IProcessController>();

            var build = builder.Build();

            return(build.BeginLifetimeScope());
        }
Exemplo n.º 29
0
        public ILifetimeScope CreateScope(ILifetimeScope scope, IPipelineLogger logger)
        {
            var process = scope.Resolve <Process>();

            var builder = new ContainerBuilder();

            builder.Properties["Process"] = process;

            builder.Register((ctx) => process).As <Process>();
            builder.RegisterInstance(logger).As <IPipelineLogger>().SingleInstance();
            builder.RegisterModule(new CsScriptModule());
            builder.RegisterModule(new BogusModule());
            RegisterTransform(builder, c => new HashcodeTransform(c), new[] { new OperationSignature("hashcode") });

            // Process Context
            builder.Register <IContext>((ctx, p) => new PipelineContext(logger, process)).As <IContext>();

            // Process Output Context
            builder.Register(ctx => {
                var context = ctx.Resolve <IContext>();
                return(new OutputContext(context));
            }).As <OutputContext>();

            // Connection and Process Level Output Context
            foreach (var connection in process.Connections)
            {
                builder.Register(ctx => new ConnectionContext(ctx.Resolve <IContext>(), connection)).Named <IConnectionContext>(connection.Key);

                if (connection.Name != "output")
                {
                    continue;
                }

                // register output for connection
                builder.Register(ctx => {
                    var context = ctx.ResolveNamed <IConnectionContext>(connection.Key);
                    return(new OutputContext(context));
                }).Named <OutputContext>(connection.Key);
            }

            // Entity Context and RowFactory
            foreach (var entity in process.Entities)
            {
                builder.Register <IContext>((ctx, p) => new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity)).Named <IContext>(entity.Key);

                builder.Register(ctx => {
                    var context = ctx.ResolveNamed <IContext>(entity.Key);
                    return(new InputContext(context));
                }).Named <InputContext>(entity.Key);

                builder.Register <IRowFactory>((ctx, p) => new RowFactory(p.Named <int>("capacity"), entity.IsMaster, false)).Named <IRowFactory>(entity.Key);

                builder.Register(ctx => {
                    var context = ctx.ResolveNamed <IContext>(entity.Key);
                    return(new OutputContext(context));
                }).Named <OutputContext>(entity.Key);

                var connection = process.Connections.First(c => c.Name == entity.Connection);
                builder.Register(ctx => new ConnectionContext(ctx.Resolve <IContext>(), connection)).Named <IConnectionContext>(entity.Key);
            }

            // Entity input
            foreach (var entity in process.Entities.Where(e => process.Connections.First(c => c.Name == e.Connection).Provider == "internal"))
            {
                builder.RegisterType <NullInputProvider>().Named <IInputProvider>(entity.Key);

                // READER
                builder.Register <IRead>(ctx => {
                    var input      = ctx.ResolveNamed <InputContext>(entity.Key);
                    var rowFactory = ctx.ResolveNamed <IRowFactory>(entity.Key, new NamedParameter("capacity", input.RowCapacity));

                    return(new InternalReader(input, rowFactory));
                }).Named <IRead>(entity.Key);
            }

            // PROCESS OUTPUT CONTROLLER
            builder.Register <IOutputController>(ctx => new NullOutputController()).As <IOutputController>();

            // Entity Output
            foreach (var entity in process.Entities)
            {
                builder.Register <IOutputController>(ctx => new NullOutputController()).Named <IOutputController>(entity.Key);
                builder.Register <IOutputProvider>(ctx => new InternalOutputProvider(ctx.ResolveNamed <OutputContext>(entity.Key), ctx.ResolveNamed <IWrite>(entity.Key))).Named <IOutputProvider>(entity.Key);

                // WRITER
                builder.Register <IWrite>(ctx => new InternalWriter(ctx.ResolveNamed <OutputContext>(entity.Key))).Named <IWrite>(entity.Key);
            }

            // entity pipelines
            foreach (var entity in process.Entities)
            {
                builder.Register(ctx => {
                    var context          = ctx.ResolveNamed <IContext>(entity.Key);
                    var outputController = ctx.IsRegisteredWithName <IOutputController>(entity.Key) ? ctx.ResolveNamed <IOutputController>(entity.Key) : new NullOutputController();
                    IPipeline pipeline   = new DefaultPipeline(outputController, context);

                    // TODO: rely on IInputProvider's Read method instead (after every provider has one)
                    pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IRead)) ? ctx.ResolveNamed <IRead>(entity.Key) : null);
                    pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IInputProvider)) ? ctx.ResolveNamed <IInputProvider>(entity.Key) : null);

                    // transforms
                    if (!process.ReadOnly)
                    {
                        pipeline.Register(new SetSystemFields(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity)));
                    }

                    pipeline.Register(new IncrementTransform(context));
                    pipeline.Register(new LogTransform(context));
                    pipeline.Register(new DefaultTransform(context, context.GetAllEntityFields().Where(f => !f.System)));
                    pipeline.Register(TransformFactory.GetTransforms(ctx, context, entity.GetAllFields().Where(f => f.Transforms.Any())));

                    if (!process.ReadOnly)
                    {
                        pipeline.Register(new StringTruncateTransfom(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity)));
                    }

                    pipeline.Register(new LogTransform(context));

                    // writer, TODO: rely on IOutputProvider instead
                    pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IWrite)) ? ctx.ResolveNamed <IWrite>(entity.Key) : null);
                    pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IOutputProvider)) ? ctx.ResolveNamed <IOutputProvider>(entity.Key) : null);

                    // updater
                    pipeline.Register(process.ReadOnly || !ctx.IsRegisteredWithName(entity.Key, typeof(IUpdate)) ? new NullUpdater() : ctx.ResolveNamed <IUpdate>(entity.Key));

                    return(pipeline);
                }).Named <IPipeline>(entity.Key);
            }


            // process pipeline
            builder.Register(ctx => {
                var calc   = process.ToCalculatedFieldsProcess();
                var entity = calc.Entities.First();

                var context = new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity);

                context.Debug(() => $"Registering {process.Pipeline} pipeline.");
                var outputController = ctx.IsRegistered <IOutputController>() ? ctx.Resolve <IOutputController>() : new NullOutputController();
                IPipeline pipeline   = new DefaultPipeline(outputController, context);

                // no updater necessary
                pipeline.Register(new NullUpdater(context, false));

                if (!process.CalculatedFields.Any())
                {
                    pipeline.Register(new NullReader(context, false));
                    pipeline.Register(new NullWriter(context, false));
                    return(pipeline);
                }

                // register transforms
                pipeline.Register(new IncrementTransform(context));
                pipeline.Register(new LogTransform(context));
                pipeline.Register(new DefaultTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity), entity.CalculatedFields));
                pipeline.Register(TransformFactory.GetTransforms(ctx, context, entity.CalculatedFields));
                pipeline.Register(new StringTruncateTransfom(new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity)));

                pipeline.Register(new NullReader(context));
                pipeline.Register(new NullWriter(context));

                return(pipeline);
            }).As <IPipeline>();

            // process controller
            builder.Register <IProcessController>(ctx => {
                var pipelines = new List <IPipeline>();

                // entity-level pipelines
                foreach (var entity in process.Entities)
                {
                    var pipeline = ctx.ResolveNamed <IPipeline>(entity.Key);

                    pipelines.Add(pipeline);
                    if (entity.Delete && process.Mode != "init")
                    {
                        pipeline.Register(ctx.ResolveNamed <IEntityDeleteHandler>(entity.Key));
                    }
                }

                // process-level pipeline for process level calculated fields
                if (ctx.IsRegistered <IPipeline>())
                {
                    pipelines.Add(ctx.Resolve <IPipeline>());
                }

                var context = ctx.Resolve <IContext>();

                var controller = new ProcessController(pipelines, context);

                // actions
                foreach (var action in process.Actions.Where(a => a.GetModes().Any(m => m == process.Mode || m == "*")))
                {
                    if (action.Before)
                    {
                        controller.PreActions.Add(ctx.ResolveNamed <IAction>(action.Key));
                    }
                    if (action.After)
                    {
                        controller.PostActions.Add(ctx.ResolveNamed <IAction>(action.Key));
                    }
                }

                return(controller);
            }).As <IProcessController>();

            var build = builder.Build();

            return(build.BeginLifetimeScope());
        }