public static EntryElement ToEntry(EventRecord evnt, string userHostName) { if (evnt == null || userHostName == null) { return(null); } var entry = new EntryElement(); entry.SetTitle(String.Format("{0} #{1}", evnt.EventStreamId, evnt.EventNumber)); entry.SetId(HostName.Combine(userHostName, "/streams/{0}/{1}", evnt.EventStreamId, evnt.EventNumber)); entry.SetUpdated(evnt.TimeStamp); entry.SetAuthor(AtomSpecs.Author); entry.SetSummary(String.Format("Entry #{0}", evnt.EventNumber)); entry.AddLink(HostName.Combine(userHostName, "/streams/{0}/{1}", evnt.EventStreamId, evnt.EventNumber), "edit", null); entry.AddLink( HostName.Combine(userHostName, "/streams/{0}/event/{1}?format=text", evnt.EventStreamId, evnt.EventNumber), null, ContentType.PlainText); entry.AddLink( HostName.Combine(userHostName, "/streams/{0}/event/{1}?format=json", evnt.EventStreamId, evnt.EventNumber), "alternate", ContentType.Json); entry.AddLink( HostName.Combine(userHostName, "/streams/{0}/event/{1}?format=xml", evnt.EventStreamId, evnt.EventNumber), "alternate", ContentType.Xml); return(entry); }
public static FeedElement ToAllEventsBackwardFeed(ClientMessage.ReadAllEventsBackwardCompleted msg, Uri requestedUrl, EmbedLevel embedContent) { var self = HostName.Combine(requestedUrl, "/streams/{0}", AllEscaped); var feed = new FeedElement(); feed.SetTitle(string.Format("All events")); feed.SetId(self); feed.SetUpdated(msg.Events.Length > 0 && msg.Events[0].Event != null ? msg.Events[0].Event.TimeStamp : DateTime.MinValue.ToUniversalTime()); feed.SetAuthor(AtomSpecs.Author); feed.AddLink("self", self); feed.AddLink("first", HostName.Combine(requestedUrl, "/streams/{0}/head/backward/{1}", AllEscaped, msg.MaxCount)); if (!msg.IsEndOfStream) { feed.AddLink("last", HostName.Combine(requestedUrl, "/streams/{0}/{1}/forward/{2}", AllEscaped, new TFPos(0, 0).AsString(), msg.MaxCount)); feed.AddLink("next", HostName.Combine(requestedUrl, "/streams/{0}/{1}/backward/{2}", AllEscaped, msg.NextPos.AsString(), msg.MaxCount)); } feed.AddLink("previous", HostName.Combine(requestedUrl, "/streams/{0}/{1}/forward/{2}", AllEscaped, msg.PrevPos.AsString(), msg.MaxCount)); feed.AddLink("metadata", HostName.Combine(requestedUrl, "/streams/{0}/metadata", AllEscaped)); for (int i = 0; i < msg.Events.Length; ++i) { feed.AddEntry( ToEntry( new ResolvedEvent(msg.Events[i].Event, msg.Events[i].Link, msg.Events[i].ResolveResult), requestedUrl, embedContent)); } return(feed); }
public static ResponseConfiguration WriteEventsCompleted(HttpResponseConfiguratorArgs entity, Message message, string eventStreamId) { var msg = message as ClientMessage.WriteEventsCompleted; if (msg != null) { switch (msg.Result) { case OperationResult.Success: var location = HostName.Combine(entity.RequestedUrl, "/streams/{0}/{1}", Uri.EscapeDataString(eventStreamId), msg.FirstEventNumber); return new ResponseConfiguration(HttpStatusCode.Created, "Created", "text/plain", Helper.UTF8NoBom, new KeyValuePair<string, string>("Location", location)); case OperationResult.PrepareTimeout: case OperationResult.CommitTimeout: case OperationResult.ForwardTimeout: return InternalServerError("Write timeout"); case OperationResult.WrongExpectedVersion: return BadRequest("Wrong expected EventNumber"); case OperationResult.StreamDeleted: return Gone("Stream deleted"); case OperationResult.InvalidTransaction: return InternalServerError("Invalid transaction"); case OperationResult.AccessDenied: return Unauthorized(); default: throw new ArgumentOutOfRangeException(); } } var notHandled = message as ClientMessage.NotHandled; if (notHandled != null) return HandleNotHandled(entity.RequestedUrl, notHandled); return InternalServerError(); }
public static FeedElement ToStreamEventBackwardFeed(ClientMessage.ReadStreamEventsBackwardCompleted msg, Uri requestedUrl, EmbedLevel embedContent, bool headOfStream) { Ensure.NotNull(msg, "msg"); string escapedStreamId = Uri.EscapeDataString(msg.EventStreamId); var self = HostName.Combine(requestedUrl, "/streams/{0}", escapedStreamId); var feed = new FeedElement(); feed.SetTitle(string.Format("Event stream '{0}'", msg.EventStreamId)); feed.StreamId = msg.EventStreamId; feed.SetId(self); feed.SetUpdated(msg.Events.Length > 0 && msg.Events[0].Event != null ? msg.Events[0].Event.TimeStamp : DateTime.MinValue.ToUniversalTime()); feed.SetAuthor(AtomSpecs.Author); feed.SetHeadOfStream(headOfStream); //TODO AN: remove this ? feed.SetSelfUrl(self); //TODO AN: remove this ? if (headOfStream) //NOTE: etag workaround - to be fixed with better http handling model { feed.SetETag(Configure.GetPositionETag(msg.LastEventNumber, ContentType.AtomJson)); } var prevEventNumber = Math.Min(msg.FromEventNumber, msg.LastEventNumber) + 1; var nextEventNumber = msg.FromEventNumber - msg.MaxCount; feed.AddLink("self", self); feed.AddLink("first", HostName.Combine(requestedUrl, "/streams/{0}/head/backward/{1}", escapedStreamId, msg.MaxCount)); if (!msg.IsEndOfStream) { if (nextEventNumber < 0) { throw new Exception(string.Format("nextEventNumber is negative: {0} while IsEndOfStream", nextEventNumber)); } feed.AddLink("last", HostName.Combine(requestedUrl, "/streams/{0}/{1}/forward/{2}", escapedStreamId, 0, msg.MaxCount)); feed.AddLink("next", HostName.Combine(requestedUrl, "/streams/{0}/{1}/backward/{2}", escapedStreamId, nextEventNumber, msg.MaxCount)); } feed.AddLink("previous", HostName.Combine(requestedUrl, "/streams/{0}/{1}/forward/{2}", escapedStreamId, prevEventNumber, msg.MaxCount)); feed.AddLink("metadata", HostName.Combine(requestedUrl, "/streams/{0}/metadata", escapedStreamId)); for (int i = 0; i < msg.Events.Length; ++i) { feed.AddEntry(ToEntry(msg.Events[i], requestedUrl, embedContent)); } return(feed); }
public static ServiceDocument ToServiceDocument(IEnumerable <string> userStreams, IEnumerable <string> systemStreams, string userHostName) { if (userStreams == null || systemStreams == null || userHostName == null) { return(null); } var document = new ServiceDocument(); var userWorkspace = new WorkspaceElement(); userWorkspace.SetTitle("User event streams"); var systemWorkspace = new WorkspaceElement(); systemWorkspace.SetTitle("System event streams"); foreach (var userStream in userStreams) { var collection = new CollectionElement(); collection.SetTitle(userStream); collection.SetUri(HostName.Combine(userHostName, "/streams/{0}", userStream)); collection.AddAcceptType(ContentType.Xml); collection.AddAcceptType(ContentType.Atom); collection.AddAcceptType(ContentType.Json); collection.AddAcceptType(ContentType.AtomJson); userWorkspace.AddCollection(collection); } foreach (var systemStream in systemStreams) { var collection = new CollectionElement(); collection.SetTitle(systemStream); collection.SetUri(HostName.Combine(userHostName, "/streams/{0}", systemStream)); collection.AddAcceptType(ContentType.Xml); collection.AddAcceptType(ContentType.Atom); collection.AddAcceptType(ContentType.Json); collection.AddAcceptType(ContentType.AtomJson); systemWorkspace.AddCollection(collection); } document.AddWorkspace(userWorkspace); document.AddWorkspace(systemWorkspace); return(document); }
public static FeedElement ToFeed(string eventStreamId, int start, int count, DateTime updateTime, EventRecord[] items, Func <EventRecord, string, EntryElement> itemToEntry, string userHostName) { if (string.IsNullOrEmpty(eventStreamId) || items == null || userHostName == null) { return(null); } if (start == -1) { start = GetActualStart(items); } var self = HostName.Combine(userHostName, "/streams/{0}", eventStreamId); var feed = new FeedElement(); feed.SetTitle(String.Format("Event stream '{0}'", eventStreamId)); feed.SetId(self); feed.SetUpdated(updateTime); feed.SetAuthor(AtomSpecs.Author); feed.AddLink(self, "self", null); feed.AddLink(HostName.Combine(userHostName, "/streams/{0}/range/{1}/{2}", eventStreamId, AtomSpecs.FeedPageSize - 1, AtomSpecs.FeedPageSize), "first", null); feed.AddLink(HostName.Combine(userHostName, "/streams/{0}/range/{1}/{2}", eventStreamId, PrevStart(start), AtomSpecs.FeedPageSize), "prev", null); feed.AddLink(HostName.Combine(userHostName, "/streams/{0}/range/{1}/{2}", eventStreamId, NextStart(start), AtomSpecs.FeedPageSize), "next", null); foreach (var item in items) { feed.AddEntry(itemToEntry(item, userHostName)); } return(feed); }
public static FeedElement ToNextNPersistentMessagesFeed(ClientMessage.ReadNextNPersistentMessagesCompleted msg, Uri requestedUrl, string streamId, string groupName, int count, EmbedLevel embedContent) { string escapedStreamId = Uri.EscapeDataString(streamId); string escapedGroupName = Uri.EscapeDataString(groupName); var self = HostName.Combine(requestedUrl, "/subscriptions/{0}/{1}", escapedStreamId, escapedGroupName); var feed = new FeedElement(); feed.SetTitle(string.Format("Messages for '{0}/{1}'", streamId, groupName)); feed.SetId(self); feed.SetUpdated(msg.Events.Length > 0 && msg.Events[0].ResolvedEvent.Event != null ? msg.Events[msg.Events.Length - 1].ResolvedEvent.Event.TimeStamp : DateTime.MinValue.ToUniversalTime()); feed.SetAuthor(AtomSpecs.Author); if (msg.Events != null && msg.Events.Length > 0) { var ackAllQueryString = String.Format("?ids={0}", String.Join(",", msg.Events.Select(x => x.ResolvedEvent.OriginalEvent.EventId))); var ackAll = HostName.Combine(requestedUrl, "/subscriptions/{0}/{1}/ack", escapedStreamId, escapedGroupName) + ackAllQueryString; feed.AddLink("ackAll", ackAll); var nackAllQueryString = String.Format("?ids={0}", String.Join(",", msg.Events.Select(x => x.ResolvedEvent.OriginalEvent.EventId))); var nackAll = HostName.Combine(requestedUrl, "/subscriptions/{0}/{1}/nack", escapedStreamId, escapedGroupName) + nackAllQueryString; feed.AddLink("nackAll", nackAll); } var prev = HostName.Combine(requestedUrl, "/subscriptions/{0}/{1}/{2}", escapedStreamId, escapedGroupName, count); feed.AddLink("previous", prev); feed.AddLink("self", self); for (int i = msg.Events.Length - 1; i >= 0; --i) { var entry = ToEntry(msg.Events[i].ResolvedEvent.WithoutPosition(), requestedUrl, embedContent); var ack = HostName.Combine(requestedUrl, "/subscriptions/{0}/{1}/ack/{2}", escapedStreamId, escapedGroupName, msg.Events[i].ResolvedEvent.OriginalEvent.EventId); var nack = HostName.Combine(requestedUrl, "/subscriptions/{0}/{1}/nack/{2}", escapedStreamId, escapedGroupName, msg.Events[i].ResolvedEvent.OriginalEvent.EventId); entry.AddLink("ack", ack); entry.AddLink("nack", nack); entry.AddRetryCount(msg.Events[i].RetryCount); feed.AddEntry(entry); } return(feed); }
private static void SetEntryProperties(string stream, int eventNumber, DateTime timestamp, Uri requestedUrl, EntryElement entry) { var escapedStreamId = Uri.EscapeDataString(stream); entry.SetTitle(eventNumber + "@" + stream); entry.SetId(HostName.Combine(requestedUrl, "/streams/{0}/{1}", escapedStreamId, eventNumber)); entry.SetUpdated(timestamp); entry.SetAuthor(AtomSpecs.Author); entry.AddLink("edit", HostName.Combine(requestedUrl, "/streams/{0}/{1}", escapedStreamId, eventNumber)); entry.AddLink("alternate", HostName.Combine(requestedUrl, "/streams/{0}/{1}", escapedStreamId, eventNumber)); }
public static FeedElement ToStreamEventForwardFeed(ClientMessage.ReadStreamEventsForwardCompleted msg, Uri requestedUrl, EmbedLevel embedContent) { Ensure.NotNull(msg, "msg"); string escapedStreamId = Uri.EscapeDataString(msg.EventStreamId); var self = HostName.Combine(requestedUrl, "/streams/{0}", escapedStreamId); var feed = new FeedElement(); feed.SetTitle(string.Format("Event stream '{0}'", msg.EventStreamId)); feed.StreamId = msg.EventStreamId; feed.SetId(self); feed.SetUpdated(msg.Events.Length > 0 && msg.Events[0].Event != null ? msg.Events[0].Event.TimeStamp : DateTime.MinValue.ToUniversalTime()); feed.SetAuthor(AtomSpecs.Author); feed.SetHeadOfStream(msg.IsEndOfStream); var prevEventNumber = Math.Min(msg.FromEventNumber + msg.MaxCount - 1, msg.LastEventNumber) + 1; var nextEventNumber = msg.FromEventNumber - 1; feed.AddLink("self", self); feed.AddLink("first", HostName.Combine(requestedUrl, "/streams/{0}/head/backward/{1}", escapedStreamId, msg.MaxCount)); if (nextEventNumber >= 0) { feed.AddLink("last", HostName.Combine(requestedUrl, "/streams/{0}/{1}/forward/{2}", escapedStreamId, 0, msg.MaxCount)); feed.AddLink("next", HostName.Combine(requestedUrl, "/streams/{0}/{1}/backward/{2}", escapedStreamId, nextEventNumber, msg.MaxCount)); } if (!msg.IsEndOfStream || msg.Events.Length > 0) { feed.AddLink("previous", HostName.Combine(requestedUrl, "/streams/{0}/{1}/forward/{2}", escapedStreamId, prevEventNumber, msg.MaxCount)); } if (!escapedStreamId.StartsWith("$$")) { feed.AddLink("metadata", HostName.Combine(requestedUrl, "/streams/{0}/metadata", escapedStreamId)); } for (int i = msg.Events.Length - 1; i >= 0; --i) { feed.AddEntry(ToEntry(msg.Events[i], requestedUrl, embedContent)); } return(feed); }
public static FeedElement ToAllEventsBackwardFeed(ReadAllResult result, Func <EventRecord, string, EntryElement> itemToEntry, string userHostName) { var self = HostName.Combine(userHostName, "/streams/$all"); var feed = new FeedElement(); feed.SetTitle(String.Format("All events")); feed.SetId(self); var items = result.Records.Select(rer => rer.Event).ToList(); feed.SetUpdated(items.Any() ? items.First().TimeStamp : DateTime.MinValue.ToUniversalTime()); feed.SetAuthor(AtomSpecs.Author); feed.AddLink(self, "self", null); feed.AddLink(HostName.Combine(userHostName, "/streams/$all/{0}", result.MaxCount), "first", null); feed.AddLink(HostName.Combine(userHostName, "/streams/$all/after/{0}/{1}", new TFPos(0, 0).AsString(), result.MaxCount), "last", null); feed.AddLink(HostName.Combine(userHostName, "/streams/$all/after/{0}/{1}", result.PrevPos.AsString(), result.MaxCount), "prev", null); feed.AddLink(HostName.Combine(userHostName, "/streams/$all/before/{0}/{1}", result.NextPos.AsString(), result.MaxCount), "next", null); foreach (var item in items) { feed.AddEntry(itemToEntry(item, userHostName)); } return(feed); }
public static ResponseConfiguration WriteEventsCompleted(HttpEntity entity, Message message) { Debug.Assert(message.GetType() == typeof(ClientMessage.WriteEventsCompleted)); var completed = message as ClientMessage.WriteEventsCompleted; if (completed == null) { return(InternalServerEror(entity, message)); } switch (completed.ErrorCode) { case OperationErrorCode.Success: return(new ResponseConfiguration(HttpStatusCode.Created, "Created", null, new KeyValuePair <string, string>("Location", HostName.Combine(entity.UserHostName, "/streams/{0}/{1}", completed.EventStreamId, completed.EventNumber == 0 ? 1 : completed.EventNumber)))); case OperationErrorCode.PrepareTimeout: case OperationErrorCode.CommitTimeout: case OperationErrorCode.ForwardTimeout: return(new ResponseConfiguration(HttpStatusCode.InternalServerError, "Write timeout", null)); case OperationErrorCode.WrongExpectedVersion: return(new ResponseConfiguration(HttpStatusCode.BadRequest, "Wrong expected version", null)); case OperationErrorCode.StreamDeleted: return(new ResponseConfiguration(HttpStatusCode.Gone, "Stream deleted", null)); case OperationErrorCode.InvalidTransaction: return(new ResponseConfiguration(HttpStatusCode.InternalServerError, "Invalid transaction", null)); default: throw new ArgumentOutOfRangeException(); } }
public static FeedElement ToAllEventsForwardFilteredFeed(ClientMessage.FilteredReadAllEventsForwardCompleted msg, Uri requestedUrl, EmbedLevel embedContent) { var self = HostName.Combine(requestedUrl, "/streams/{0}", AllFilteredEscaped); var feed = new FeedElement(); feed.SetTitle("All events"); feed.SetId(self); feed.SetUpdated(msg.Events.Length > 0 && msg.Events[0].Event != null ? msg.Events[msg.Events.Length - 1].Event.TimeStamp : DateTime.MinValue.ToUniversalTime()); feed.SetAuthor(AtomSpecs.Author); feed.AddLink("self", self); feed.AddLink("first", HostName.Combine(requestedUrl, "/streams/{0}/head/backward/{1}", AllFilteredEscaped, msg.MaxCount)); if (msg.CurrentPos.CommitPosition != 0) { feed.AddLink("last", HostName.Combine(requestedUrl, "/streams/{0}/{1}/forward/{2}", AllFilteredEscaped, new TFPos(0, 0).AsString(), msg.MaxCount)); feed.AddLink("next", HostName.Combine(requestedUrl, "/streams/{0}/{1}/backward/{2}", AllFilteredEscaped, msg.PrevPos.AsString(), msg.MaxCount)); } if (!msg.IsEndOfStream || msg.Events.Length > 0) { feed.AddLink("previous", HostName.Combine(requestedUrl, "/streams/{0}/{1}/forward/{2}", AllFilteredEscaped, msg.NextPos.AsString(), msg.MaxCount)); } for (int i = msg.Events.Length - 1; i >= 0; --i) { feed.AddEntry(ToEntry(msg.Events[i].WithoutPosition(), requestedUrl, embedContent)); } return(feed); }
public static EntryElement ToEntry(ResolvedEvent eventLinkPair, Uri requestedUrl, EmbedLevel embedContent, bool singleEntry = false) { if (eventLinkPair.Event == null || requestedUrl == null) { return(null); } var evnt = eventLinkPair.Event; EntryElement entry; if (embedContent > EmbedLevel.Content) { var richEntry = new RichEntryElement(); entry = richEntry; richEntry.EventType = evnt.EventType; richEntry.EventNumber = evnt.EventNumber; richEntry.StreamId = evnt.EventStreamId; richEntry.PositionEventNumber = eventLinkPair.OriginalEvent.EventNumber; richEntry.PositionStreamId = eventLinkPair.OriginalEvent.EventStreamId; richEntry.IsJson = (evnt.Flags & PrepareFlags.IsJson) != 0; if (embedContent >= EmbedLevel.Body) { if (richEntry.IsJson) { if (embedContent >= EmbedLevel.PrettyBody) { try { richEntry.Data = Helper.UTF8NoBom.GetString(evnt.Data); // next step may fail, so we have already assigned body richEntry.Data = FormatJson(Helper.UTF8NoBom.GetString(evnt.Data)); } catch { // ignore - we tried } } else { richEntry.Data = Helper.UTF8NoBom.GetString(evnt.Data); } } else if (embedContent >= EmbedLevel.TryHarder) { try { richEntry.Data = Helper.UTF8NoBom.GetString(evnt.Data); // next step may fail, so we have already assigned body richEntry.Data = FormatJson(richEntry.Data); // it is json if successed richEntry.IsJson = true; } catch { // ignore - we tried } } // metadata if (embedContent >= EmbedLevel.PrettyBody) { try { richEntry.MetaData = Helper.UTF8NoBom.GetString(evnt.Metadata); richEntry.IsMetaData = richEntry.MetaData.IsNotEmptyString(); // next step may fail, so we have already assigned body richEntry.MetaData = FormatJson(richEntry.MetaData); } catch { // ignore - we tried } var lnk = eventLinkPair.Link; if (lnk != null) { try { richEntry.LinkMetaData = Helper.UTF8NoBom.GetString(lnk.Metadata); richEntry.IsLinkMetaData = richEntry.LinkMetaData.IsNotEmptyString(); // next step may fail, so we have already assigned body richEntry.LinkMetaData = FormatJson(richEntry.LinkMetaData); } catch { // ignore - we tried } } } } } else { entry = new EntryElement(); } var escapedStreamId = Uri.EscapeDataString(evnt.EventStreamId); entry.SetTitle(evnt.EventNumber + "@" + evnt.EventStreamId); entry.SetId(HostName.Combine(requestedUrl, "/streams/{0}/{1}", escapedStreamId, evnt.EventNumber)); entry.SetUpdated(evnt.TimeStamp); entry.SetAuthor(AtomSpecs.Author); entry.SetSummary(evnt.EventType); if ((singleEntry || embedContent == EmbedLevel.Content) && ((evnt.Flags & PrepareFlags.IsJson) != 0)) { entry.SetContent(AutoEventConverter.CreateDataDto(eventLinkPair)); } entry.AddLink("edit", HostName.Combine(requestedUrl, "/streams/{0}/{1}", escapedStreamId, evnt.EventNumber)); entry.AddLink("alternate", HostName.Combine(requestedUrl, "/streams/{0}/{1}", escapedStreamId, evnt.EventNumber)); return(entry); }