Exemple #1
0
 public CommandContext(
     string entityId,
     long sequence,
     string commandName,
     long commandId,
     AnySupport anySupport,
     IEventSourcedEntityHandler eventSourcedEntityHandler,
     int snapshotEvery,
     AbstractContext abstractContext,
     AbstractClientActionContext abstractClientActionContext,
     AbstractEffectContext abstractEffectContext,
     IActivatableContext activatableContext)
 {
     EntityId    = entityId;
     Sequence    = sequence;
     CommandName = commandName;
     CommandId   = commandId;
     AnySupport  = anySupport;
     EventSourcedEntityHandler   = eventSourcedEntityHandler;
     SnapshotEvery               = snapshotEvery;
     AbstractContext             = abstractContext;
     AbstractClientActionContext = abstractClientActionContext;
     AbstractEffectContext       = abstractEffectContext;
     ActivatableContext          = activatableContext;
 }
Exemple #2
0
 public void HandleEvent(Any @event, IEventContext context)
 {
     Unwrap(() =>
     {
         var obj = AnySupport.Decode(@event);
         if (!CurrentBehaviors
             .Any(behavior => GetCachedBehaviorReflection(behavior)
                  .GetEventHandler(obj.GetType())
                  .Match(handler =>
         {
             var active = true;
             var ctx = new EventBehaviorContext(context, behaviors =>
             {
                 // ReSharper disable once AccessToModifiedClosure
                 if (!active)
                 {
                     throw new InvalidOperationException("Context is not active!");
                 }
                 CurrentBehaviors = ValidateBehaviors(behaviors).ToArray();
             });
             handler.Invoke(behavior, obj, ctx);
             active = false;
             return(true);
         },
                         () => false)
                  )
             )
         {
             throw new CloudStateException(
                 $"No event handler [{obj.GetType()}] found for any of the current behaviors: {BehaviorsString}");
         }
     });
 }
Exemple #3
0
        public static IEventSourcedEntityHandler CreateHandler <T>(Func <IEventSourcedEntityCreationContext, object> entityFactory = null)
        {
            var anySupport = new AnySupport(
                new[] { Com.Example.Shoppingcart.Persistence.DomainReflection.Descriptor }
                );
            var mockSupport = new Mock <IEventSourcedContext>();

            mockSupport.Setup(x => x.EntityId)
            .Returns("foo");

            var method = new ResolvedServiceMethod <string, Wrapped>(
                Com.Example.Shoppingcart.ShoppingCart
                .Descriptor.Methods
                .First(x => x.Name == "AddItem"),
                new StringResolvedType(),
                new WrappedResolvedType()
                );

            return(new AttributeBasedEntityHandlerFactory(
                       typeof(T),
                       anySupport,
                       new[] { method }.ToDictionary(
                           x => x.Descriptor.Name,
                           x => x as IResolvedServiceMethod),
                       entityFactory
                       ).CreateEntityHandler(mockSupport.Object));
        }
Exemple #4
0
 public void HandleSnapshot(Any anySnapshot, ISnapshotContext context)
 {
     Unwrap(() =>
     {
         var snapshot = AnySupport.Decode(anySnapshot);
         if (!CurrentBehaviors.Any(behavior => BehaviorReflectionCache.GetOrAdd(behavior.GetType())
                                   .GetSnapshotHandler(snapshot.GetType())
                                   .Match(handler =>
         {
             var active = true;
             var ctx = new SnapshotBehaviorContext(context, behaviors =>
             {
                 // TODO: Check sequence number override on this context is set correctly.
                 // ReSharper disable once AccessToModifiedClosure
                 if (!active)
                 {
                     throw new InvalidOperationException("Context is not active!");
                 }
                 CurrentBehaviors = ValidateBehaviors(behaviors).ToArray();
             });
             handler.Invoke(behavior, snapshot, ctx);
             active = false;
             return(true);
         }, () => false))
             )
         {
             throw new CloudStateException(
                 $"No snapshot handler found for snapshot [{snapshot.GetType()}] on any of the current behaviors [{BehaviorsString}]"
                 );
         }
     });
 }
Exemple #5
0
        internal EventSourcedEntityHandler(AnySupport anySupport, IEventSourcedContext context, IBehaviorResolver behaviorReflectionCache, Func <IEventSourcedEntityCreationContext, object> entityCreationFactory = null)
        {
            AnySupport              = anySupport;
            Context                 = context;
            EntityCreationFactory   = entityCreationFactory;
            BehaviorReflectionCache = behaviorReflectionCache;

            var explicitBehaviors = Option.None <object[]>();
            var active            = true;

            void Become(object[] behaviors)
            {
                // ReSharper disable once AccessToModifiedClosure
                if (!active)
                {
                    throw new InvalidOperationException("Context is not active!");
                }
                explicitBehaviors = Option.Some(ValidateBehaviors(behaviors).ToArray());
            }

            var ctx    = new EventSourcedEntityCreationContext(context, Become);
            var entity = EntityCreationFactory(ctx);

            active           = false;
            CurrentBehaviors = explicitBehaviors.Match(behaviors => behaviors, () => new[] { entity });
        }
 public CrdtStatefulService(
     ICrdtEntityHandlerFactory factory,
     ServiceDescriptor descriptor,
     AnySupport anySupport) : base(factory, descriptor, anySupport)
 {
     Factory  = factory;
     Streamed = descriptor.Methods.Where(x => x.IsServerStreaming).Select(x => x.Name).ToArray();
 }
 protected EntityHandlerFactory(Type initialClass, AnySupport anySupport, Func <TContext, object> factory,
                                IReadOnlyDictionary <string, IResolvedServiceMethod> resolvedMethods)
 {
     InitialClass    = initialClass;
     AnySupport      = anySupport;
     Factory         = Constructor(InitialClass, factory);
     ResolvedMethods = resolvedMethods;
 }
Exemple #8
0
//        [Fact(Skip = "Not ready")]
        public void SupportSerializingAndDeserializingProtobufs()
        {
            var any = AnySupport.Encode(AddLineItem);

            Assert.Equal("type.googleapis.com/" + AddLineItem.Descriptor.FullName,
                         any.TypeUrl);
            Assert.Equal(AddLineItem, AnySupport.Decode(any));
        }
 public AttributeBasedEntityHandlerFactory(
     Type initialClass,
     AnySupport anySupport,
     IReadOnlyDictionary <string, IResolvedServiceMethod> resolvedMethods = null,
     Func <IEventSourcedEntityCreationContext, object> factory            = null
     ) : base(initialClass, anySupport, factory, resolvedMethods)
 {
     BehaviorResolver = new ReflectionCacheBehaviorResolver(() => ResolvedMethods);
     InitCache();
 }
 public AttributeBasedEntityHandlerFactory(
     Type initialClass,
     AnySupport anySupport,
     ServiceDescriptor descriptor,
     Func <IEventSourcedContext, object> factory = null
     ) : base(initialClass, anySupport, factory, anySupport.ResolveServiceDescriptor(descriptor))
 {
     BehaviorResolver = new ReflectionCacheBehaviorResolver(() => ResolvedMethods);
     InitCache();
 }
 protected StatefulEntityService(IEntityHandlerFactory <TContext, THandler> factory, ServiceDescriptor serviceDescriptor, AnySupport anySupport, string persistenceId = null)
 {
     EntityHandlerFactory = factory;
     ServiceDescriptor    = serviceDescriptor;
     AnySupport           = anySupport;
     Methods = factory switch
     {
         IResolvedEntityFactory resolved => resolved.ResolvedMethods,
                                _ => new Dictionary <string, IResolvedServiceMethod>()
     };
     PersistenceId = persistenceId ?? ServiceDescriptor.Name;
 }
Exemple #12
0
        public void TestPrimitive(string name, object value, object defaultValue)
        {
            var any = AnySupport.Encode(value);
            var res = AnySupport.Decode(any);

            Assert.Equal(value, res);

            // TODO: support for encoding (null as type)
            // any = AnySupport.Encode(null);
            // res = AnySupport.Decode(any);
            // Assert.Equal(defaultValue, res);
        }
Exemple #13
0
        public void TestPrimitiveBytes()
        {
            var str   = "foo";
            var bytes = ByteString.CopyFromUtf8(str);
            var any   = AnySupport.Encode(bytes);
            var res   = AnySupport.Decode(any) as ByteString;

            Assert.NotNull(res);
            Assert.Equal(bytes, res);

            var val = res.ToStringUtf8();

            Assert.Equal(str, val);
        }
Exemple #14
0
        public static IInternalCrdt Create(CrdtState state, AnySupport anySupport)
        {
            IInternalCrdt crdt = null;

            switch (state.StateCase)
            {
            case CrdtState.StateOneofCase.Gcounter:
                crdt = new GCounterImpl();
                break;

            default:
                throw new NotImplementedException();
            }
            crdt.ApplyState(state);
            return(crdt);
        }
Exemple #15
0
        internal static IEventSourcedEntityHandler CreateHandler <T>(Func <IEventSourcedEntityCreationContext, object> entityFactory = null)
        {
            var anySupport = new AnySupport(
                new[] { Com.Example.Shoppingcart.Persistence.DomainReflection.Descriptor }
                );
            var mockSupport = new Mock <IEventSourcedContext>();

            mockSupport.Setup(x => x.EntityId)
            .Returns("foo");

            return(new AttributeBasedEntityHandlerFactory(
                       typeof(T),
                       anySupport,
                       new IResolvedServiceMethod[] { }.ToDictionary(
                           x => x.Descriptor.Name,
                           x => x),
                       entityFactory
                       ).CreateEntityHandler(mockSupport.Object));
        }
        protected internal AttributeBasedCrdtHandlerFactory(Type initialClass, AnySupport anySupport, ServiceDescriptor descriptor, Func <ICrdtEntityCreationContext, object> factory = null)
            : base(initialClass, anySupport, factory, anySupport.ResolveServiceDescriptor(descriptor))
        {
            var allMethods = ReflectionHelper.GetAllDeclaredMethods(initialClass);
            var handlers   = allMethods.Where(x => x.GetCustomAttribute <CommandHandlerAttribute>() != null)
                             .Select(method =>
            {
                var attribute = method.GetCustomAttribute <CommandHandlerAttribute>();
                var name      = string.IsNullOrEmpty(attribute.Name)
                        ? ReflectionHelper.GetCapitalizedName(method)
                        : attribute.Name;
                if (!ResolvedMethods.TryGetValue(name, out var serviceMethod))
                {
                    throw new CloudStateException(
                        $"Command handler method [{method.Name}] for command [{name}] found, but the service has no command by that name.");
                }
                return(method, serviceMethod);
            }).ToArray();

            CommandHandlers         = GetHandlers <ICommandContext>(handlers, false);
            StreamedCommandHandlers = GetHandlers <IStreamedCommandContext <ICommandContext> >(handlers, true);
        }
Exemple #17
0
        public void ResolveServiceDescriptor()
        {
            var methods = AnySupport.ResolveServiceDescriptor(
                ShoppingcartReflection.Descriptor.FindTypeByName <ServiceDescriptor>("ShoppingCart")
                );

            Assert.Equal(3, methods.Count);

            var method = methods["AddItem"].Method;

            Assert.Equal(AddLineItem.Descriptor.FullName, method.InputType.FullName);
            Assert.Equal(typeof(AddLineItem), method.InputType.ClrType);
            var bytes = AddLineItem.ToByteString();

            Assert.Equal(AddLineItem, method.InputType.Parser.ParseFrom(bytes));

            Assert.Equal(Empty.Descriptor.FullName, method.OutputType.FullName);
            Assert.Equal(typeof(Empty), method.OutputType.ClrType);
            var defaultEmpty = new Empty();

            bytes = defaultEmpty.ToByteString();
            Assert.Equal(defaultEmpty, method.OutputType.Parser.ParseFrom(bytes));
        }
        /// <summary>
        /// Service discovery endpoint called by the CloudState operator in order to determine
        /// the list of <see cref="IStatefulService" />'s running within the current local process.
        /// </summary>
        /// <param name="request">ProxyInfo request</param>
        /// <param name="context">ServerCallContext</param>
        /// <returns></returns>
        public override async Task <EntitySpec> discover(ProxyInfo request, ServerCallContext context)
        {
            Logger.LogInformation(
                $"Received discovery call from sidecar [{request.ProxyName} {request.ProxyVersion}] supporting CloudState {request.ProtocolMajorVersion}.{request.ProtocolMinorVersion}"
                );
            Logger.LogDebug($"Supported sidecar entity types: {string.Join(", ", request.SupportedEntityTypes)}");

            var unsupportedServices = Services.Values.Where(service =>
                                                            !request.SupportedEntityTypes.Contains(service.StatefulServiceTypeName)
                                                            );

            if (unsupportedServices.Any())
            {
                Logger.LogError(
                    "Proxy doesn't support the entity types for the following services: " +
                    string.Join(", ", unsupportedServices
                                .Select(s => s.ServiceDescriptor.FullName + ": " + s.StatefulServiceTypeName)
                                )
                    );
            }

            if (false)
            {
                // TODO: verify compatibility with in.protocolMajorVersion & in.protocolMinorVersion
                // await Task.FromException(new CloudStateException("Proxy version not compatible with library protocol support version"));
            }
            else
            {
                var allDescriptors = new AnySupport(Services.Values.Select(x => x.ServiceDescriptor.File)).FlattenDescriptors(
                    Services.Values.Select(x => x.ServiceDescriptor.File)
                    );

                var set = new FileDescriptorSet();
                set.File.AddRange(allDescriptors.Select(x => FileDescriptorProto.Parser.ParseFrom(x.Value.SerializedData)));
                var fileDescriptorSet = set.ToByteString();
                var entities          = Services.Select(x =>
                                                        new Entity
                {
                    EntityType    = x.Value.StatefulServiceTypeName,
                    ServiceName   = x.Key,
                    PersistenceId = x.Value.PersistenceId
                }
                                                        );

                var spec = new EntitySpec
                {
                    ServiceInfo = ServiceInfo,
                    Proto       = fileDescriptorSet
                };

                try
                {
                    spec.Entities.AddRange(entities);
                }
                catch (Exception ex)
                {
                    Logger.LogError($"Exception: {ex.StackTrace}", ex.InnerException ?? ex);
                }

                return(await Task.FromResult(spec));
            }
        }
Exemple #19
0
 internal EventSourcedStatefulService(IEventSourcedEntityHandlerFactory factory, ServiceDescriptor serviceDescriptor, AnySupport anySupport, string persistenceId = null, int snapshotEvery = 0)
     : base(factory, serviceDescriptor, anySupport, persistenceId)
 {
     SnapshotEvery = snapshotEvery;
 }