public void AttributedClass_TestMethod()
        {

            string expected = "Mock Test Event";
            string actual = "Not set";

            actual = EventNameAttribute.GetEventName(typeof(EventNameAttribute_Mock ));

            Assert.AreEqual(expected, actual);

        }
        public static IEvent Wrap(object eventPayload)
        {
            // If it already implements IEvent just return that
            IEvent ret = eventPayload as IEvent;

            if (null != ret)
            {
                return(ret);
            }
            else
            {
                // Otherwise wrap and return it
                return(new EventInstance(EventNameAttribute.GetEventName(eventPayload.GetType()), eventPayload));
            }
        }
Ejemplo n.º 3
0
        private IEnumerable <MethodInfo> GenerateExecutableMethods(IEventListener listener, IEventDescriptor eventInfo)
        {
            string eventType = EventTypeAttribute.GetEventType(listener);

            if (eventType != eventInfo.EventType)
            {
                return(Enumerable.Empty <MethodInfo>());
            }

            return(listener.GetType()
                   .GetMethods()
                   .Where(method =>
            {
                var ps = method.GetParameters();
                return ps.Length == 0 || ps.Length == 1;
            })
                   .Where(method =>
            {
                string eventName = EventNameAttribute.GetEventName(method);
                return eventName == eventInfo.EventName;
            }).ToList());
        }
        /// <summary>
        /// Append the event to the end of the event stream
        /// </summary>
        /// <param name="eventInstance">
        /// The event to append to the end of the event stream
        /// </param>
        /// <param name="expectedTopSequenceNumber">
        /// if this is set to > 0 and the event stream is further on then a consistency issue has arisen and the
        /// event should not be written but rather throw an error
        /// </param>
        /// <param name="eventVersionNumber">
        /// The version number to add to the event wrapper
        /// </param>
        /// <param name="streamConstraint">
        /// An additional constrain that must be satisfied by the event stream in order to persist the event
        /// </param>
        /// <returns></returns>
        public async Task <IAppendResult> AppendEvent(IEvent eventInstance,
                                                      int expectedTopSequenceNumber = 0,
                                                      int eventVersionNumber        = 1,
                                                      EventStreamExistenceConstraint streamConstraint = EventStreamExistenceConstraint.Loose)
        {
            if (base.EventStreamBlob != null)
            {
                // acquire a lease for the blob..
                string writeStreamLeaseId = null;
                if (await Exists())
                {
                    writeStreamLeaseId = await base.EventStreamBlob.AcquireLeaseAsync(TimeSpan.FromSeconds(15));
                }

                int nextSequence = await base.GetSequenceNumber() + 1;

                if (expectedTopSequenceNumber > 0)
                {
                    // check against actual top sequence number
                    if ((expectedTopSequenceNumber + 1) < nextSequence)
                    {
                        throw new EventStreamWriteException(this,
                                                            (nextSequence - 1),
                                                            message: $"Out of sequence write - expected seqeunce number {expectedTopSequenceNumber }",
                                                            source: "Blob Event Stream Writer");
                    }
                }

                string eventName = "";
                if (null != eventInstance)
                {
                    eventName = EventNameAttribute.GetEventName(eventInstance.GetType());
                }

                // create an access condition
                AccessCondition condition = AccessCondition.GenerateEmptyCondition();
                if (streamConstraint == EventStreamExistenceConstraint.MustBeNew)
                {
                    condition = AccessCondition.GenerateIfNotExistsCondition();
                }
                if (streamConstraint == EventStreamExistenceConstraint.MustExist)
                {
                    condition = AccessCondition.GenerateIfExistsCondition();
                }
                if (!string.IsNullOrWhiteSpace(writeStreamLeaseId))
                {
                    condition.LeaseId = writeStreamLeaseId;
                }

                // default the writer context if it is not already set
                if (null == _writerContext)
                {
                    _writerContext = WriteContext.DefaultWriterContext();
                }

                BlobBlockJsonWrappedEvent evtToWrite = BlobBlockJsonWrappedEvent.Create(eventName,
                                                                                        nextSequence,
                                                                                        eventVersionNumber,
                                                                                        null,
                                                                                        eventInstance,
                                                                                        _writerContext);

                try
                {
                    // Create it if it doesn't exist and initialsie the metadata
                    await base.Refresh();


                    Microsoft.Azure.Storage.OperationContext context = new Microsoft.Azure.Storage.OperationContext()
                    {
                    };

                    await EventStreamBlob.AppendBlockAsync(new System.IO.MemoryStream(Encoding.UTF8.GetBytes(evtToWrite.ToJSonText())),
                                                           "",
                                                           condition,
                                                           null, // use the default blob request options
                                                           context
                                                           );
                }
                catch (Microsoft.Azure.Storage.StorageException exBlob)
                {
                    throw new EventStreamWriteException(this,
                                                        (nextSequence - 1),
                                                        message: "Failed to save an event to the event stream",
                                                        source: "Blob Event Stream Writer",
                                                        innerException: exBlob);
                }

                await IncrementSequence(writeStreamLeaseId);

                if (!string.IsNullOrWhiteSpace(writeStreamLeaseId))
                {
                    // and release the lease
                    await base.EventStreamBlob.ReleaseLeaseAsync(condition);
                }

                int sequence = await base.GetSequenceNumber();

                return(new AppendResult((sequence == 0), sequence));
            }
            else
            {
                return(null);
            }
        }
Ejemplo n.º 5
0
        public DynamicTableEntity MakeDynamicTableEntity(IEvent eventToPersist,
                                                         int sequenceNumber)
        {
            DynamicTableEntity ret = new DynamicTableEntity(this.InstanceKey,
                                                            SequenceNumberAsString(sequenceNumber));

            // Add the event type
            if (!string.IsNullOrWhiteSpace(eventToPersist.EventTypeName))
            {
                // Use the event type name given
                ret.Properties.Add(FIELDNAME_EVENTTYPE,
                                   new EntityProperty(eventToPersist.EventTypeName));
            }
            else
            {
                // fall back on the .NET name of the payload class
                ret.Properties.Add(FIELDNAME_EVENTTYPE,
                                   new EntityProperty(EventNameAttribute.GetEventName(eventToPersist.GetType())));
            }

            if (null != _writerContext)
            {
                if (!string.IsNullOrWhiteSpace(_writerContext.Commentary))
                {
                    ret.Properties.Add(FIELDNAME_COMMENTS,
                                       new EntityProperty(_writerContext.Commentary));
                }
                if (!string.IsNullOrWhiteSpace(_writerContext.CorrelationIdentifier))
                {
                    ret.Properties.Add(FIELDNAME_CORRELATION_IDENTIFIER,
                                       new EntityProperty(_writerContext.CorrelationIdentifier));
                }
                if (!string.IsNullOrWhiteSpace(_writerContext.Source))
                {
                    ret.Properties.Add(FIELDNAME_SOURCE,
                                       new EntityProperty(_writerContext.Source));
                }
                if (!string.IsNullOrWhiteSpace(_writerContext.Who))
                {
                    ret.Properties.Add(FIELDNAME_WHO,
                                       new EntityProperty(_writerContext.Who));
                }
                if (!string.IsNullOrWhiteSpace(_writerContext.SchemaName))
                {
                    ret.Properties.Add(FIELDNAME_SCHEMA,
                                       new EntityProperty(_writerContext.SchemaName));
                }
            }

            if (null != eventToPersist.EventPayload)
            {
                // save the payload properties
                int propertiesCount = 0;
                foreach (System.Reflection.PropertyInfo pi in eventToPersist.EventPayload.GetType().GetProperties())
                {
                    if (pi.CanRead)
                    {
                        if (!IsContextProperty(pi.Name))
                        {
                            if (propertiesCount > MAX_FREE_DATA_FIELDS)
                            {
                                throw new EventStreamWriteException(this,
                                                                    sequenceNumber,
                                                                    $"Event has too many fields to store in an Azure table");
                            }
                            else
                            {
                                if (!IsPropertyEmpty(pi, eventToPersist.EventPayload))
                                {
                                    ret.Properties.Add(pi.Name, MakeEntityProperty(pi, eventToPersist.EventPayload));
                                }
                            }
                        }
                    }
                }
            }

            return(ret);
        }
Ejemplo n.º 6
0
        public async Task NewEventAppended(IEventStreamIdentity targetEntity,
                                           string eventType,
                                           int sequenceNumber,
                                           string commentary     = "",
                                           object eventPayload   = null,
                                           IWriteContext context = null)
        {
            string messageToSend = MakeMessageString(targetEntity,
                                                     NOTIFICATION_NEW_EVENT,
                                                     eventType,
                                                     sequenceNumber);

            string queueName = string.Empty;

            // special case - if it is a Command or Query requesting a Classification or Projection..
            if (eventType == EventNameAttribute.GetEventName(typeof(ProjectionRequested)))
            {
                // Is it a command or query...
                if (targetEntity.DomainName.Contains("Command"))
                {
                    queueName = QUEUE_COMMAND_PROJECTIONS;
                }
                if (targetEntity.DomainName.Contains("Query"))
                {
                    queueName = QUEUE_QUERY_PROJECTIONS;
                }
                // Add the extra details to the message text to indicate what projection was requested
                ProjectionRequested evtPayload = eventPayload as ProjectionRequested;
                if (evtPayload != null)
                {
                    messageToSend += ProjectionRequested.ToQueueMessage(evtPayload);
                }
            }
            else
            {
                if (eventType == EventNameAttribute.GetEventName(typeof(ClassifierRequested)))
                {
                    // Is it a command or query...
                    if (targetEntity.DomainName.Contains("Command"))
                    {
                        queueName = QUEUE_COMMAND_CLASSIFICATIONS;
                    }
                    if (targetEntity.DomainName.Contains("Query"))
                    {
                        queueName = QUEUE_QUERY_CLASSIFICATIONS;
                    }
                    // Add the extra details to the message text to indicate what classification was requested
                    ClassifierRequested evtPayload = eventPayload as ClassifierRequested;
                    if (evtPayload != null)
                    {
                        messageToSend += $"|{evtPayload.DomainName}|{evtPayload.EntityTypeName}|{evtPayload.InstanceKey}|{evtPayload.ClassifierTypeName}|{evtPayload.AsOfDate}|{evtPayload.CorrelationIdentifier}";
                    }
                }
                else
                {
                    queueName = MakeQueueName(targetEntity);
                }
            }

            string connectionStringName = _eventStreamSettings.GetConnectionStringName(targetEntity);

            if (!string.IsNullOrWhiteSpace(queueName))
            {
                await SendQueueMessage(connectionStringName, queueName, messageToSend);
            }
        }