public void CreateMessageReaderShouldSetAnnotationFilterWhenODataAnnotationIsSetOnPreferenceAppliedHeader() { IODataResponseMessage responseMessage = new InMemoryMessage(); responseMessage.PreferenceAppliedHeader().AnnotationFilter = "*"; ODataMessageReader reader = new ODataMessageReader(responseMessage, new ODataMessageReaderSettings()); reader.Settings.ShouldIncludeAnnotation.Should().NotBeNull(); }
public void CreateMessageReaderShouldNotSetAnnotationFilterWhenItIsAlreadySet() { IODataResponseMessage responseMessage = new InMemoryMessage(); responseMessage.PreferenceAppliedHeader().AnnotationFilter = "*"; Func<string, bool> shouldWrite = name => false; ODataMessageReader reader = new ODataMessageReader(responseMessage, new ODataMessageReaderSettings { ShouldIncludeAnnotation = shouldWrite }); reader.Settings.ShouldIncludeAnnotation.Should().BeSameAs(shouldWrite); }
private void WriteAnnotationsAndValidatePayload(Action<ODataWriter> action, IEdmNavigationSource navigationSource, ODataFormat format, string expectedPayload, bool request, bool createFeedWriter) { var writerSettings = new ODataMessageWriterSettings {DisableMessageStreamDisposal = true, EnableAtom = true}; writerSettings.SetContentType(format); writerSettings.SetServiceDocumentUri(new Uri("http://www.example.com/")); MemoryStream stream = new MemoryStream(); if (request) { IODataRequestMessage requestMessageToWrite = new InMemoryMessage { Method = "GET", Stream = stream }; using (var messageWriter = new ODataMessageWriter(requestMessageToWrite, writerSettings, Model)) { ODataWriter odataWriter = (createFeedWriter && !(navigationSource is EdmSingleton)) ? messageWriter.CreateODataFeedWriter(navigationSource as EdmEntitySet, EntityType) : messageWriter.CreateODataEntryWriter(navigationSource, EntityType); ; action(odataWriter); } } else { IODataResponseMessage responseMessageToWrite = new InMemoryMessage { StatusCode = 200, Stream = stream }; responseMessageToWrite.PreferenceAppliedHeader().AnnotationFilter = "*"; using (var messageWriter = new ODataMessageWriter(responseMessageToWrite, writerSettings, Model)) { ODataWriter odataWriter = (createFeedWriter && !(navigationSource is EdmSingleton)) ? messageWriter.CreateODataFeedWriter(navigationSource as EdmEntitySet, EntityType) : messageWriter.CreateODataEntryWriter(navigationSource, EntityType); ; action(odataWriter); } } stream.Position = 0; string payload = (new StreamReader(stream)).ReadToEnd(); if (format == ODataFormat.Atom) { // The <updated> element is computed dynamically, so we remove it from the both the baseline and the actual payload. payload = Regex.Replace(payload, "<updated>[^<]*</updated>", ""); expectedPayload = Regex.Replace(expectedPayload, "<updated>[^<]*</updated>", ""); } Assert.AreEqual(expectedPayload, payload); }
private void WriteDeltaFeedAnnotationsAndValidatePayload(Action<ODataDeltaWriter> action, IEdmEntitySet entitySet, string expectedPayload) { var writerSettings = new ODataMessageWriterSettings {DisableMessageStreamDisposal = true}; writerSettings.SetServiceDocumentUri(new Uri("http://www.example.com/")); MemoryStream stream = new MemoryStream(); IODataResponseMessage responseMessageToWrite = new InMemoryMessage {StatusCode = 200, Stream = stream}; responseMessageToWrite.PreferenceAppliedHeader().AnnotationFilter = "*"; using (var messageWriter = new ODataMessageWriter(responseMessageToWrite, writerSettings, Model)) { ODataDeltaWriter odataDeltaWriter = messageWriter.CreateODataDeltaWriter(entitySet, EntityType); action(odataDeltaWriter); } stream.Position = 0; string payload = (new StreamReader(stream)).ReadToEnd(); Assert.AreEqual(expectedPayload, payload); }
public void WriteTopLevelEntityReferenceLinks() { ODataEntityReferenceLink link1 = new ODataEntityReferenceLink { Url = new Uri("http://host/Customers(1)") }; link1.InstanceAnnotations.Add(new ODataInstanceAnnotation("Is.New", new ODataPrimitiveValue(true))); ODataEntityReferenceLink link2 = new ODataEntityReferenceLink { Url = new Uri("http://host/Customers(2)") }; link2.InstanceAnnotations.Add(new ODataInstanceAnnotation("TestNamespace.unknown", new ODataPrimitiveValue(123))); link2.InstanceAnnotations.Add(new ODataInstanceAnnotation("custom.annotation", new ODataPrimitiveValue(456))); ODataEntityReferenceLinks referencelinks = new ODataEntityReferenceLinks() { Links = new[] { link1, link2 } }; var writerSettings = new ODataMessageWriterSettings { DisableMessageStreamDisposal = true }; writerSettings.SetContentType(ODataFormat.Json); writerSettings.SetServiceDocumentUri(new Uri("http://odata.org/test")); MemoryStream stream = new MemoryStream(); IODataResponseMessage requestMessageToWrite = new InMemoryMessage { StatusCode = 200, Stream = stream }; requestMessageToWrite.PreferenceAppliedHeader().AnnotationFilter = "*"; using (var messageWriter = new ODataMessageWriter(requestMessageToWrite, writerSettings, EdmModel)) { messageWriter.WriteEntityReferenceLinks(referencelinks); } stream.Position = 0; string payload = (new StreamReader(stream)).ReadToEnd(); string expectedPayload = "{\"@odata.context\":\"http://odata.org/test/$metadata#Collection($ref)\",\"value\":[{\"@odata.id\":\"http://host/Customers(1)\",\"@Is.New\":true},{\"@odata.id\":\"http://host/Customers(2)\",\"@TestNamespace.unknown\":123,\"@custom.annotation\":456}]}"; Assert.AreEqual(expectedPayload, payload); }
private void ReadEntryPayload(string payload, Action<ODataReader> action) { var message = new InMemoryMessage() { Stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)) }; message.SetHeader("Content-Type", "application/atom+xml;type=entry"); message.PreferenceAppliedHeader().AnnotationFilter = "*"; using (var msgReader = new ODataMessageReader((IODataResponseMessage)message, atomReaderSettings)) { var reader = msgReader.CreateODataEntryReader(); while (reader.Read()) { action(reader); } } }
private static void WriteCustomInstanceAnnotationToFeedAndEntry(string expectedPayload, ODataFormat format) { var writerSettings = new ODataMessageWriterSettings { DisableMessageStreamDisposal = true, EnableAtom = format == ODataFormat.Atom }; writerSettings.SetContentType(format); writerSettings.ODataUri = new ODataUri() { ServiceRoot = new Uri("http://www.example.com/") }; MemoryStream stream = new MemoryStream(); IODataResponseMessage messageToWrite = new InMemoryMessage { StatusCode = 200, Stream = stream }; messageToWrite.PreferenceAppliedHeader().AnnotationFilter = "Custom.*"; // Write payload using (var messageWriter = new ODataMessageWriter(messageToWrite, writerSettings, Model)) { var odataWriter = messageWriter.CreateODataFeedWriter(EntitySet, EntityType); // Add instance annotations to the feed. var feedToWrite = new ODataFeed { Id = new Uri("urn:feedId") }; feedToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("Custom.Int32Annotation", PrimitiveValue1)); feedToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("Custom.GuidAnnotation", PrimitiveValue2)); feedToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("ShouldSkip.Int32Annotation", PrimitiveValue1)); feedToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("ShouldSkip.GuidAnnotation", PrimitiveValue2)); // Writes instance annotations at the beginning of the feed odataWriter.WriteStart(feedToWrite); // Add instance annotations to the entry. var entryToWrite = new ODataEntry { Properties = new[] { new ODataProperty { Name = "ID", Value = 1 } } }; entryToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("Custom.ComplexAnnotation", ComplexValue1)); entryToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("ShouldSkip.ComplexAnnotation", ComplexValue1)); // Writes instance annotations at the beginning of the entry odataWriter.WriteStart(entryToWrite); // Add more instance annotations to the entry. entryToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("Custom.PrimitiveCollectionAnnotation", PrimitiveCollectionValue)); entryToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("ShouldSkip.PrimitiveCollectionAnnotation", PrimitiveCollectionValue)); // The writer remembers which instance annotations in the collection has been written // and only write out the unwritten ones since WriteStart() to the end of the entry. odataWriter.WriteEnd(); // Add more instance annotations to the feed. feedToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("Custom.ComplexCollectionAnnotation", ComplexCollectionValue)); feedToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("ShouldSkip.ComplexCollectionAnnotation", ComplexCollectionValue)); // The writer remembers which instance annotations in the collection has been written // and only write out the unwritten ones since WriteStart() to the end of the feed. odataWriter.WriteEnd(); } stream.Position = 0; string payload = (new StreamReader(stream)).ReadToEnd(); if (format == ODataFormat.Atom) { // The <updated> element is computed dynamically, so we remove it from the both the baseline and the actual payload. payload = Regex.Replace(payload, "<updated>[^<]*</updated>", ""); expectedPayload = Regex.Replace(expectedPayload, "<updated>[^<]*</updated>", ""); } payload.Should().Be(expectedPayload); }
public void ShouldBeAbleToReadCustomInstanceAnnotationFromFeedAndEntry(string payload, string contentType) { var stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)); var readerSettings = new ODataMessageReaderSettings { DisableMessageStreamDisposal = false, EnableAtom = true }; IODataResponseMessage messageToRead = new InMemoryMessage { StatusCode = 200, Stream = stream }; messageToRead.SetHeader("Content-Type", contentType); // Enable reading custom instance annotations. messageToRead.PreferenceAppliedHeader().AnnotationFilter = "Custom.*"; Stack<ODataItem> odataItems = new Stack<ODataItem>(4); using (var messageReader = new ODataMessageReader(messageToRead, readerSettings, Model)) { var odataReader = messageReader.CreateODataFeedReader(EntitySet, EntityType); ICollection<ODataInstanceAnnotation> instanceAnnotations = null; while (odataReader.Read()) { switch (odataReader.State) { case ODataReaderState.FeedStart: odataItems.Push(odataReader.Item); instanceAnnotations = odataItems.Peek().As<ODataFeed>().InstanceAnnotations; // TODO: We only support instance annotation at the top level feed at the moment. Will remove the if statement when support on inline feed is added. if (odataItems.Count == 1) { // Note that in streaming mode, the collection should be populated with instance annotations read so far before the beginning of the first entry. // We are currently in non-streaming mode. The reader will buffer the payload and read ahead till the // end of the feed to read all instance annotations. instanceAnnotations.Should().HaveCount(1); TestUtils.AssertODataValueAreEqual(new ODataPrimitiveValue(odataItems.Count), instanceAnnotations.Single(ia => ia.Name == "Custom.FeedStartAnnotation").Value); } else { instanceAnnotations.Should().BeEmpty(); } break; case ODataReaderState.FeedEnd: instanceAnnotations = odataItems.Peek().As<ODataFeed>().InstanceAnnotations; // TODO: We only support instance annotation at the top level feed at the moment. Will remove the if statement when support on inline feed is added. if (odataItems.Count == 1) { instanceAnnotations.Should().HaveCount(2); TestUtils.AssertODataValueAreEqual(new ODataPrimitiveValue(1), instanceAnnotations.Single(ia => ia.Name == "Custom.FeedStartAnnotation").Value); TestUtils.AssertODataValueAreEqual(new ODataPrimitiveValue(1), instanceAnnotations.Single(ia => ia.Name == "Custom.FeedEndAnnotation").Value); } else { instanceAnnotations.Should().BeEmpty(); } odataItems.Pop(); break; case ODataReaderState.NavigationLinkStart: ODataNavigationLink navigationLink = (ODataNavigationLink)odataReader.Item; if (navigationLink.Name == "ResourceSetNavigationProperty") { // The collection should be populated with instance annotations read so far before the "ResourceSetNavigationProperty". instanceAnnotations = odataItems.Peek().As<ODataEntry>().InstanceAnnotations; instanceAnnotations.Should().HaveCount(2); TestUtils.AssertODataValueAreEqual(new ODataPrimitiveValue(odataItems.Count), instanceAnnotations.Single(ia => ia.Name == "Custom.EntryStartAnnotation").Value); TestUtils.AssertODataValueAreEqual(new ODataPrimitiveValue(odataItems.Count), instanceAnnotations.Single(ia => ia.Name == "Custom.EntryMiddleAnnotation").Value); } break; case ODataReaderState.NavigationLinkEnd: break; case ODataReaderState.EntryStart: odataItems.Push(odataReader.Item); // The collection should be populated with instance annotations read so far before the first navigation/association link or before the end of the entry. instanceAnnotations = odataItems.Peek().As<ODataEntry>().InstanceAnnotations; instanceAnnotations.Should().HaveCount(1); TestUtils.AssertODataValueAreEqual(new ODataPrimitiveValue(odataItems.Count), instanceAnnotations.Single(ia => ia.Name == "Custom.EntryStartAnnotation").Value); break; case ODataReaderState.EntryEnd: instanceAnnotations = odataItems.Peek().As<ODataEntry>().InstanceAnnotations; instanceAnnotations.Should().HaveCount(3); TestUtils.AssertODataValueAreEqual(new ODataPrimitiveValue(odataItems.Count), instanceAnnotations.Single(ia => ia.Name == "Custom.EntryStartAnnotation").Value); TestUtils.AssertODataValueAreEqual(new ODataPrimitiveValue(odataItems.Count), instanceAnnotations.Single(ia => ia.Name == "Custom.EntryMiddleAnnotation").Value); TestUtils.AssertODataValueAreEqual(new ODataPrimitiveValue(odataItems.Count), instanceAnnotations.Single(ia => ia.Name == "Custom.EntryEndAnnotation").Value); odataItems.Pop(); break; } } instanceAnnotations.Should().HaveCount(2); TestUtils.AssertODataValueAreEqual(new ODataPrimitiveValue(1), instanceAnnotations.Single(ia => ia.Name == "Custom.FeedStartAnnotation").Value); TestUtils.AssertODataValueAreEqual(new ODataPrimitiveValue(1), instanceAnnotations.Single(ia => ia.Name == "Custom.FeedEndAnnotation").Value); } }
private static ODataMessageReader CreateODataMessageReader(string payload, string contentType, bool isResponse, bool shouldReadAndValidateCustomInstanceAnnotations) { var stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)); var readerSettings = new ODataMessageReaderSettings { DisableMessageStreamDisposal = false, EnableAtom = true }; ODataMessageReader messageReader; if (isResponse) { IODataResponseMessage responseMessage = new InMemoryMessage { StatusCode = 200, Stream = stream }; responseMessage.SetHeader("Content-Type", contentType); if (shouldReadAndValidateCustomInstanceAnnotations) { responseMessage.PreferenceAppliedHeader().AnnotationFilter = "*"; } messageReader = new ODataMessageReader(responseMessage, readerSettings, Model); } else { IODataRequestMessage requestMessage = new InMemoryMessage { Method = "GET", Stream = stream }; requestMessage.SetHeader("Content-Type", contentType); readerSettings.ShouldIncludeAnnotation = shouldReadAndValidateCustomInstanceAnnotations ? ODataUtils.CreateAnnotationFilter("*") : null; messageReader = new ODataMessageReader(requestMessage, readerSettings, Model); } return messageReader; }