public async Task ReadDeletedLinkInDeltaResourceSetWorksAsExpected2() { // Arrange string payload = "{\"@context\":\"http://example.com/$metadata#Customers/$delta\"," + "\"value\":[" + "{" + "\"@removed\":{\"reason\":\"changed\"}," + "\"CustomerID\":1," + "\"Order@delta\":{" + "\"@context\":\"#Orders/$deletedEntity\"," + "\"@removed\":{\"reason\":\"deleted\"}," + "\"OrderId\":10" + "}" + "}" + "]" + "}"; IEdmEntitySet customers = Model.EntityContainer.FindEntitySet("Customers"); Assert.NotNull(customers); // Guard // Act Func <ODataMessageReader, Task <ODataReader> > func = mr => mr.CreateODataDeltaResourceSetReaderAsync(customers, customers.EntityType()); ODataItemWrapper item = await ReadPayloadAsync(payload, Model, func, ODataVersion.V401); // Assert Assert.NotNull(item); // --- DeltaResourceSet // |--- DeleteResource (Changed) // |--- NestedResourceInfo // |--- DeleteResource (Deleted) ODataDeltaResourceSetWrapper deltaResourceSet = Assert.IsType <ODataDeltaResourceSetWrapper>(item); ODataItemWrapper deltaItem = Assert.Single(deltaResourceSet.DeltaItems); ODataResourceWrapper deletedResourceWrapper = Assert.IsType <ODataResourceWrapper>(deltaItem); ODataDeletedResource deletedResource = Assert.IsType <ODataDeletedResource>(deletedResourceWrapper.Resource); Assert.Equal(DeltaDeletedEntryReason.Changed, deletedResource.Reason); ODataNestedResourceInfoWrapper nestedResourceInfo = Assert.Single(deletedResourceWrapper.NestedResourceInfos); Assert.Equal("Order", nestedResourceInfo.NestedResourceInfo.Name); Assert.False(nestedResourceInfo.NestedResourceInfo.IsCollection); ODataItemWrapper nestedItem = Assert.Single(nestedResourceInfo.NestedItems); ODataResourceWrapper orderResource = Assert.IsType <ODataResourceWrapper>(nestedItem); Assert.True(orderResource.IsDeletedResource); ODataDeletedResource innerDeletedResource = Assert.IsType <ODataDeletedResource>(orderResource.Resource); Assert.Equal(DeltaDeletedEntryReason.Deleted, innerDeletedResource.Reason); ODataProperty property = Assert.Single(innerDeletedResource.Properties); Assert.Equal("OrderId", property.Name); Assert.Equal(10, property.Value); }
private void ApplyNestedDeltaResourceSet(IEdmProperty nestedProperty, object resource, ODataDeltaResourceSetWrapper deltaResourceSetWrapper, ODataDeserializerContext readContext) { Contract.Assert(nestedProperty != null); Contract.Assert(resource != null); Contract.Assert(readContext != null); IEdmTypeReference edmType = nestedProperty.Type; ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(edmType, true); if (deserializer == null) { throw new SerializationException(Error.Format(SRResources.TypeCannotBeDeserialized, edmType.FullName())); } IEdmStructuredTypeReference structuredType = edmType.AsCollection().ElementType().AsStructured(); ODataDeserializerContext nestedReadContext = readContext.CloneWithoutType(); if (readContext.IsNoClrType) { nestedReadContext.ResourceType = typeof(EdmChangedObjectCollection); } else { Type clrType = readContext.Model.GetClrType(structuredType); if (clrType == null) { throw new ODataException( Error.Format(SRResources.MappingDoesNotContainResourceType, structuredType.FullName())); } nestedReadContext.ResourceType = typeof(DeltaSet <>).MakeGenericType(clrType); } object value = deserializer.ReadInline(deltaResourceSetWrapper, edmType, nestedReadContext); string propertyName = readContext.Model.GetClrPropertyName(nestedProperty); DeserializationHelpers.SetCollectionProperty(resource, nestedProperty, value, propertyName); }
public void ReadDeltaResourceSet_Calls_ReadInlineForEachDeltaItem() { // Arrange IEdmModel model = GetEdmModel(); IEdmEntityType customer = model.SchemaElements.OfType <IEdmEntityType>().First(c => c.Name == "Customer"); IEdmStructuredTypeReference elementType = new EdmEntityTypeReference(customer, true); Mock <IODataDeserializerProvider> deserializerProvider = new Mock <IODataDeserializerProvider>(); Mock <ODataEdmTypeDeserializer> resourceDeserializer = new Mock <ODataEdmTypeDeserializer>(ODataPayloadKind.Resource); ODataDeltaResourceSetDeserializer deserializer = new ODataDeltaResourceSetDeserializer(deserializerProvider.Object); ODataDeltaResourceSetWrapper deltaResourceSetWrapper = new ODataDeltaResourceSetWrapper(new ODataDeltaResourceSet()); Uri source = new Uri("Customers(8)", UriKind.RelativeOrAbsolute); Uri target = new Uri("Orders(10645)", UriKind.RelativeOrAbsolute); deltaResourceSetWrapper.DeltaItems.Add(new ODataResourceWrapper(new ODataResource { Id = new Uri("http://a1/") })); deltaResourceSetWrapper.DeltaItems.Add(new ODataResourceWrapper(new ODataDeletedResource { Id = new Uri("http://a2/") })); ODataDeserializerContext readContext = new ODataDeserializerContext() { Model = model, ResourceType = typeof(DeltaSet <>) }; deserializerProvider.Setup(p => p.GetEdmTypeDeserializer(elementType, false)).Returns(resourceDeserializer.Object); resourceDeserializer.Setup(d => d.ReadInline(deltaResourceSetWrapper.DeltaItems[0], elementType, It.IsAny <ODataDeserializerContext>())).Returns("entry1").Verifiable(); resourceDeserializer.Setup(d => d.ReadInline(deltaResourceSetWrapper.DeltaItems[1], elementType, It.IsAny <ODataDeserializerContext>())).Returns("entry2").Verifiable(); // Act var result = deserializer.ReadDeltaResourceSet(deltaResourceSetWrapper, elementType, readContext); // Assert Assert.Equal(new[] { "entry1", "entry2" }, result.OfType <String>()); resourceDeserializer.Verify(); }
public void ReadInline_Calls_ReadDeltaResourceSet() { // Arrange EdmEntityType entityType = new EdmEntityType("NS", "Customer"); IEdmEntityTypeReference entityTypeRef = new EdmEntityTypeReference(entityType, false); IEdmCollectionTypeReference collectionType = new EdmCollectionTypeReference(new EdmCollectionType(entityTypeRef)); Mock <IODataDeserializerProvider> deserializerProvider = new Mock <IODataDeserializerProvider>(); Mock <ODataDeltaResourceSetDeserializer> deserializer = new Mock <ODataDeltaResourceSetDeserializer>(deserializerProvider.Object); ODataDeltaResourceSetWrapper wrapper = new ODataDeltaResourceSetWrapper(new ODataDeltaResourceSet()); ODataDeserializerContext readContext = new ODataDeserializerContext(); deserializer.CallBase = true; deserializer.Setup(d => d.ReadDeltaResourceSet(wrapper, It.IsAny <IEdmStructuredTypeReference>(), readContext)).Returns((IEnumerable)null).Verifiable(); // Act var result = deserializer.Object.ReadInline(wrapper, collectionType, readContext); // Assert deserializer.Verify(); Assert.Null(result); }
/// <summary> /// Deserializes the given <paramref name="deltaResourceSet"/> under the given <paramref name="readContext"/>. /// </summary> /// <param name="deltaResourceSet">The delta resource set to deserialize.</param> /// <param name="elementType">The element type.</param> /// <param name="readContext">The deserializer context.</param> /// <returns>The deserialized resource set object.</returns> public virtual IEnumerable ReadDeltaResourceSet(ODataDeltaResourceSetWrapper deltaResourceSet, IEdmStructuredTypeReference elementType, ODataDeserializerContext readContext) { if (deltaResourceSet == null) { throw Error.ArgumentNull(nameof(deltaResourceSet)); } if (readContext == null) { throw Error.ArgumentNull(nameof(readContext)); } // Delta Items foreach (ODataItemWrapper itemWrapper in deltaResourceSet.DeltaItems) { // Deleted Link ODataDeltaDeletedLinkWrapper deletedLinkWrapper = itemWrapper as ODataDeltaDeletedLinkWrapper; if (deletedLinkWrapper != null) { yield return(ReadDeltaDeletedLink(deletedLinkWrapper, elementType, readContext)); } // Added Link ODataDeltaLinkWrapper deltaLinkWrapper = itemWrapper as ODataDeltaLinkWrapper; if (deltaLinkWrapper != null) { yield return(ReadDeltaLink(deltaLinkWrapper, elementType, readContext)); } // Added resource, updated resource and deleted resource ODataResourceWrapper resourceWrapper = itemWrapper as ODataResourceWrapper; if (resourceWrapper != null) { yield return(ReadDeltaResource(resourceWrapper, elementType, readContext)); } } }
/// <inheritdoc /> public sealed override object ReadInline(object item, IEdmTypeReference edmType, ODataDeserializerContext readContext) { if (item == null) { return(null); } if (edmType == null) { throw Error.ArgumentNull(nameof(edmType)); } if (readContext == null) { throw Error.ArgumentNull(nameof(readContext)); } if (!edmType.IsCollection() || !edmType.AsCollection().ElementType().IsStructured()) { throw Error.Argument(nameof(edmType), SRResources.TypeMustBeResourceSet, edmType.ToTraceString()); } ODataDeltaResourceSetWrapper resourceSet = item as ODataDeltaResourceSetWrapper; if (resourceSet == null) { throw Error.Argument(nameof(item), SRResources.ArgumentMustBeOfType, typeof(ODataResourceSetWrapper).Name); } // Recursion guard to avoid stack overflows RuntimeHelpers.EnsureSufficientExecutionStack(); IEdmStructuredTypeReference elementType = edmType.AsCollection().ElementType().AsStructured(); IEnumerable result = ReadDeltaResourceSet(resourceSet, readContext); if (result != null && elementType.IsComplex()) { if (readContext.IsNoClrType) { EdmComplexObjectCollection complexCollection = new EdmComplexObjectCollection(edmType.AsCollection()); foreach (EdmComplexObject complexObject in result) { complexCollection.Add(complexObject); } return(complexCollection); } else { Type elementClrType = readContext.Model.GetClrType(elementType); IEnumerable castedResult = CastMethodInfo.MakeGenericMethod(elementClrType).Invoke(null, new object[] { result }) as IEnumerable; return(castedResult); } } else { return(result); } }
/// <summary> /// Deserializes the given <paramref name="deltaResourceSet"/> under the given <paramref name="readContext"/>. /// </summary> /// <param name="deltaResourceSet">The delta resource set to deserialize.</param> /// <param name="readContext">The deserializer context.</param> /// <returns>The deserialized resource set object.</returns> public virtual IEnumerable ReadDeltaResourceSet(ODataDeltaResourceSetWrapper deltaResourceSet, ODataDeserializerContext readContext) { if (deltaResourceSet == null) { throw Error.ArgumentNull(nameof(deltaResourceSet)); } if (readContext == null) { throw Error.ArgumentNull(nameof(readContext)); } // resource foreach (ODataResourceBaseWrapper resourceBaseWrapper in deltaResourceSet.ResourceBases) { ODataResourceWrapper resourceWrapper = resourceBaseWrapper as ODataResourceWrapper; ODataDeletedResourceWrapper deletedResourceWrapper = resourceBaseWrapper as ODataDeletedResourceWrapper; if (resourceWrapper != null) { IEdmModel model = readContext.Model; if (model == null) { throw Error.Argument("readContext", SRResources.ModelMissingFromReadContext); } IEdmStructuredType actualType = model.FindType(resourceWrapper.Resource.TypeName) as IEdmStructuredType; if (actualType == null) { throw new ODataException(Error.Format(SRResources.ResourceTypeNotInModel, resourceWrapper.Resource.TypeName)); } IEdmTypeReference edmTypeReference = actualType.ToEdmTypeReference(true); ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(edmTypeReference); if (deserializer == null) { throw new SerializationException( Error.Format(SRResources.TypeCannotBeDeserialized, edmTypeReference.FullName())); } // TODO: normal resource yield return(deserializer.ReadInline(resourceWrapper, edmTypeReference, readContext)); } else { // TODO: deleted resource } } // Delta links foreach (ODataDeltaLinkBaseWrapper deltaLinkBaseWrapper in deltaResourceSet.DeltaLinks) { ODataDeltaDeletedLinkWrapper deletedLinkWrapper = deltaLinkBaseWrapper as ODataDeltaDeletedLinkWrapper; if (deletedLinkWrapper != null) { yield return(ReadDeltaDeletedLink(deletedLinkWrapper, readContext)); } else { yield return(ReadDeltaLink((ODataDeltaLinkWrapper)deltaLinkBaseWrapper, readContext)); } } }
/// <inheritdoc /> public sealed override object ReadInline(object item, IEdmTypeReference edmType, ODataDeserializerContext readContext) { if (item == null) { return(null); } if (edmType == null) { throw Error.ArgumentNull(nameof(edmType)); } if (readContext == null) { throw Error.ArgumentNull(nameof(readContext)); } if (!edmType.IsCollection() || !edmType.AsCollection().ElementType().IsStructured()) { throw Error.Argument(nameof(edmType), SRResources.TypeMustBeResourceSet, edmType.ToTraceString()); } ODataDeltaResourceSetWrapper resourceSet = item as ODataDeltaResourceSetWrapper; if (resourceSet == null) { throw Error.Argument(nameof(item), SRResources.ArgumentMustBeOfType, typeof(ODataDeltaResourceSetWrapper).Name); } // Recursion guard to avoid stack overflows RuntimeHelpers.EnsureSufficientExecutionStack(); IEdmStructuredTypeReference elementType = edmType.AsCollection().ElementType().AsStructured(); IEnumerable result = ReadDeltaResourceSet(resourceSet, elementType, readContext); if (result != null) { if (readContext.IsNoClrType) { EdmChangedObjectCollection changedObjCollection = new EdmChangedObjectCollection(elementType.Definition as IEdmEntityType); foreach (IEdmChangedObject changedObject in result) { changedObjCollection.Add(changedObject); } return(changedObjCollection); } else { Type elementClrType = readContext.Model.GetClrType(elementType); Type changedObjCollType = typeof(DeltaSet <>).MakeGenericType(elementClrType); IDeltaSet deltaSet = Activator.CreateInstance(changedObjCollType) as IDeltaSet; foreach (var delta in result) { IDeltaSetItem deltaItem = delta as IDeltaSetItem; if (deltaItem != null) { deltaSet.Add(deltaItem); } } return(deltaSet); } } else { return(result); } }
public async Task ReadDeletedLinkInDeltaResourceSetWorksAsExpected() { // Arrange string payload = "{" + "\"@odata.context\":\"http://localhost/$metadata#Customers/$delta\"," + "\"@odata.count\":5," + "\"value\":[" + "{" + "\"@odata.id\":\"Customers(42)\"," + "\"Name\":\"Sammy\"" + "}," + "{" + "\"@odata.context\":\"http://localhost/$metadata#Customers/$deletedLink\"," + "\"source\":\"Customers(39)\"," + "\"relationship\":\"Orders\"," + "\"target\":\"Orders(10643)\"" + "}," + "{" + "\"@odata.context\":\"http://localhost/$metadata#Customers/$link\"," + "\"source\":\"Customers(32)\"," + "\"relationship\":\"Orders\"," + "\"target\":\"Orders(10645)\"" + "}," + "{" + "\"@odata.context\":\"http://localhost/$metadata#Orders/$entity\"," + "\"@odata.id\":\"Orders(10643)\"," + "\"Price\": 82" + "}," + "{" + "\"@odata.context\":\"http://localhost/$metadata#Customers/$deletedEntity\"," + "\"id\":\"Customers(21)\"," + "\"reason\":\"deleted\"" + "}" + "]," + "\"@odata.deltaLink\":\"Customers?$expand=Orders&$deltatoken=8015\"" + "}"; IEdmEntitySet customers = Model.EntityContainer.FindEntitySet("Customers"); Assert.NotNull(customers); // Guard // Act Func <ODataMessageReader, Task <ODataReader> > func = mr => mr.CreateODataDeltaResourceSetReaderAsync(customers, customers.EntityType()); ODataItemWrapper item = await ReadPayloadAsync(payload, Model, func); // Assert Assert.NotNull(item); // --- DeltaResourceSet // |--- Resource (1) // |--- Resource (2) // |--- DeletedResource (1) // | // |--- DeltaDeletedLink // |--- DeltaLink ODataDeltaResourceSetWrapper deltaResourceSet = Assert.IsType <ODataDeltaResourceSetWrapper>(item); // Resources Assert.Equal(3, deltaResourceSet.ResourceBases.Count); Assert.Collection(deltaResourceSet.ResourceBases, e => { ODataResourceWrapper resource1 = Assert.IsType <ODataResourceWrapper>(e); Assert.Equal("Customers(42)", resource1.Resource.Id.OriginalString); Assert.Equal("Sammy", resource1.Resource.Properties.First(p => p.Name == "Name").Value); }, e => { ODataResourceWrapper resource2 = Assert.IsType <ODataResourceWrapper>(e); Assert.Equal("Orders(10643)", resource2.Resource.Id.OriginalString); Assert.Equal(82, resource2.Resource.Properties.First(p => p.Name == "Price").Value); }, e => { ODataDeletedResourceWrapper deletedResource = Assert.IsType <ODataDeletedResourceWrapper>(e); Assert.Equal("Customers(21)", deletedResource.DeletedResource.Id.OriginalString); Assert.Equal(DeltaDeletedEntryReason.Deleted, deletedResource.DeletedResource.Reason); }); // DeltaLinks Assert.Equal(2, deltaResourceSet.DeltaLinks.Count); Assert.Collection(deltaResourceSet.DeltaLinks, e => { ODataDeltaDeletedLinkWrapper deletedLinkWrapper = Assert.IsType <ODataDeltaDeletedLinkWrapper>(e); Assert.Equal("Customers(39)", deletedLinkWrapper.DeltaDeletedLink.Source.OriginalString); Assert.Equal("Orders(10643)", deletedLinkWrapper.DeltaDeletedLink.Target.OriginalString); Assert.Equal("Orders", deletedLinkWrapper.DeltaDeletedLink.Relationship); }, e => { ODataDeltaLinkWrapper linkWrapper = Assert.IsType <ODataDeltaLinkWrapper>(e); Assert.Equal("Customers(32)", linkWrapper.DeltaLink.Source.OriginalString); Assert.Equal("Orders(10645)", linkWrapper.DeltaLink.Target.OriginalString); Assert.Equal("Orders", linkWrapper.DeltaLink.Relationship); }); }
public async Task ReadDeltaResourceSetWorksAsExpected() { // Arrange string payload = "{\"@context\":\"http://example.com/$metadata#Customers/$delta\"," + "\"value\":[" + "{" + "\"@removed\":{\"reason\":\"changed\"}," + "\"CustomerID\":1," + "\"Orders@delta\":[" + "{" + "\"@removed\":{\"reason\":\"deleted\"}," + "\"OrderId\":10" + "}," + "{" + "\"@type\":\"#NS.VipOrder\"," + "\"OrderId\":9," + "\"Email\":\"[email protected]\"" + "}" + "]" + "}" + "]" + "}"; IEdmEntitySet customers = Model.EntityContainer.FindEntitySet("Customers"); Assert.NotNull(customers); // Guard // Act Func <ODataMessageReader, Task <ODataReader> > func = mr => mr.CreateODataDeltaResourceSetReaderAsync(customers, customers.EntityType()); ODataItemWrapper item = await ReadPayloadAsync(payload, Model, func, ODataVersion.V401); // Assert Assert.NotNull(item); // --- DeltaResourceSet // |--- DeleteResource (1) // |--- NestedResourceInfo (1-1) // |--- DeltaResourceSet // |--- DelteResource // |--- Normal Resource ODataDeltaResourceSetWrapper deltaResourceSet = Assert.IsType <ODataDeltaResourceSetWrapper>(item); ODataResourceBaseWrapper resourceBase = Assert.Single(deltaResourceSet.ResourceBases); ODataDeletedResourceWrapper deletedResource = Assert.IsType <ODataDeletedResourceWrapper>(resourceBase); Assert.Equal(DeltaDeletedEntryReason.Changed, deletedResource.DeletedResource.Reason); ODataNestedResourceInfoWrapper nestedResourceInfo = Assert.Single(deletedResource.NestedResourceInfos); Assert.Equal("Orders", nestedResourceInfo.NestedResourceInfo.Name); Assert.True(nestedResourceInfo.NestedResourceInfo.IsCollection); ODataDeltaResourceSetWrapper ordersDeltaResourceSet = Assert.IsType <ODataDeltaResourceSetWrapper>(nestedResourceInfo.NestedResourceSet); Assert.Equal(2, ordersDeltaResourceSet.ResourceBases.Count); ODataDeletedResourceWrapper deletedResource1 = Assert.IsType <ODataDeletedResourceWrapper>(ordersDeltaResourceSet.ResourceBases.ElementAt(0)); Assert.Equal(DeltaDeletedEntryReason.Deleted, deletedResource1.DeletedResource.Reason); ODataResourceWrapper resource2 = Assert.IsType <ODataResourceWrapper>(ordersDeltaResourceSet.ResourceBases.ElementAt(1)); Assert.Equal("NS.VipOrder", resource2.Resource.TypeName); Assert.Collection(resource2.Resource.Properties, p => { Assert.Equal("OrderId", p.Name); Assert.Equal(9, p.Value); }, p => { Assert.Equal("Email", p.Name); Assert.Equal("*****@*****.**", p.Value); }); }
/// <summary> /// Deserializes the given <paramref name="deltaResourceSet"/> under the given <paramref name="readContext"/>. /// </summary> /// <param name="deltaResourceSet">The delta resource set to deserialize.</param> /// <param name="elementType">The element type.</param> /// <param name="readContext">The deserializer context.</param> /// <returns>The deserialized resource set object.</returns> public virtual IEnumerable ReadDeltaResourceSet(ODataDeltaResourceSetWrapper deltaResourceSet, IEdmStructuredTypeReference elementType, ODataDeserializerContext readContext) { if (deltaResourceSet == null) { throw Error.ArgumentNull(nameof(deltaResourceSet)); } if (readContext == null) { throw Error.ArgumentNull(nameof(readContext)); } // Delta Items foreach (ODataItemWrapper itemWrapper in deltaResourceSet.DeltaItems) { // Deleted Link ODataDeltaDeletedLinkWrapper deletedLinkWrapper = itemWrapper as ODataDeltaDeletedLinkWrapper; if (deletedLinkWrapper != null) { yield return(ReadDeltaDeletedLink(deletedLinkWrapper, elementType, readContext)); } // Added Link ODataDeltaLinkWrapper deltaLinkWrapper = itemWrapper as ODataDeltaLinkWrapper; if (deltaLinkWrapper != null) { yield return(ReadDeltaLink(deltaLinkWrapper, elementType, readContext)); } // DeletedResource ODataDeletedResourceWrapper deletedResourceWrapper = itemWrapper as ODataDeletedResourceWrapper; if (deletedResourceWrapper != null) { // TODO: deleted resource yield return(null); } // Added resource or updated resource ODataResourceWrapper resourceWrapper = itemWrapper as ODataResourceWrapper; if (resourceWrapper != null) { IEdmModel model = readContext.Model; if (model == null) { throw Error.Argument("readContext", SRResources.ModelMissingFromReadContext); } IEdmStructuredType actualType = model.FindType(resourceWrapper.Resource.TypeName) as IEdmStructuredType; if (actualType == null) { throw new ODataException(Error.Format(SRResources.ResourceTypeNotInModel, resourceWrapper.Resource.TypeName)); } IEdmTypeReference edmTypeReference = actualType.ToEdmTypeReference(true); ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(edmTypeReference); if (deserializer == null) { throw new SerializationException( Error.Format(SRResources.TypeCannotBeDeserialized, edmTypeReference.FullName())); } // TODO: normal resource // yield return deserializer.ReadInline(resourceWrapper, edmTypeReference, readContext); if (readContext.IsDeltaOfT) { Type elementClrType = readContext.Model.GetClrType(elementType); Type deltaType = typeof(Deltas.Delta <>).MakeGenericType(elementClrType); Deltas.IDelta delta = Activator.CreateInstance(deltaType) as Deltas.IDelta; yield return(delta); } else { yield return(new EdmDeltaResourceObject(actualType as IEdmEntityType)); } continue; } } }