/// <summary> /// Delete the given resource /// </summary> /// <param name="targetResource">resource that needs to be deleted</param> /// <remarks>This method gets a "handle" to a resource in the <paramref name="targetResource"/> and should pend a change which /// deletes that resource. /// That includes removing the resource from its resource set and freeing up all the resources associated with that resource. /// Note that this method is not called for complex type instances, only entity resurces are deleted in this way. Complex type instances /// should be deleted when the entity type which points to them is deleted. /// All changes made by this method should be creates as pending until SaveChanges is called which will commit them (or if it's not called and ClearChanges /// is called instead they should be discarded).</remarks> public virtual void DeleteResource(object targetResource) { DSPResource dspTargetResource = ValidateDSPResource(targetResource); ResourceSet resourceSet = null; ResourceType rt = dspTargetResource.ResourceType; while (rt != null) { resourceSet = rt.GetAnnotation().ResourceSet; if (resourceSet != null) { break; } rt = rt.BaseType; } IList <object> resourceSetList = this.dataContext.GetResourceSetEntities(resourceSet.Name); // Add a pending change to remove the resource from the resource set this.pendingChanges.Add(() => { resourceSetList.Remove(dspTargetResource); }); }
private static DSPServiceDefinition SetupService() { DSPMetadata metadata = new DSPMetadata("ActionsWithLargePayload", "AstoriaUnitTests.ActionTestsWithLargePayload"); var customer = metadata.AddEntityType("Customer", null, null, false); metadata.AddKeyProperty(customer, "ID", typeof(int)); var customers = metadata.AddResourceSet("Customers", customer); ComplexType = metadata.AddComplexType("AddressComplexType", null, null, false); metadata.AddPrimitiveProperty(ComplexType, "ZipCode", typeof(int)); metadata.AddPrimitiveProperty(ComplexType, "City", typeof(string)); DSPContext context = new DSPContext(); metadata.SetReadOnly(); DSPResource customer1 = new DSPResource(customer); customer1.SetValue("ID", 1); context.GetResourceSetEntities("Customers").Add(customer1); MyDSPActionProvider actionProvider = new MyDSPActionProvider(); SetUpActionWithLargeParameterPayload(actionProvider, metadata, customer); SetUpActionWithLargeCollectionParameterPayload(actionProvider, metadata, customer); SetupLargeNumberOfActions(actionProvider, metadata, customer); DSPServiceDefinition service = new DSPServiceDefinition() { Metadata = metadata, CreateDataSource = (m) => context, ForceVerboseErrors = true, Writable = true, ActionProvider = actionProvider, }; return service; }
private static void PopulateProperties(object context, object entity, DSPResource resource, Dictionary<DSPResource, object> entitiesAlreadyAdded) { Assert.IsTrue(resource.ResourceType.ResourceTypeKind != ResourceTypeKind.EntityType || entitiesAlreadyAdded.ContainsKey(resource), "entitiesAlreadyAdded.ContainsKey(resource)"); foreach (var property in resource.Properties) { ResourceProperty resourceProperty = resource.ResourceType.Properties.Single(p => p.Name == property.Key); if (resourceProperty.ResourceType.ResourceTypeKind == ResourceTypeKind.Primitive) { SetPropertyValue(entity, resourceProperty.Name, property.Value); } else if (resourceProperty.Kind == ResourcePropertyKind.ResourceReference) { DSPResource childResource = (DSPResource)property.Value; object childEntity; if (!entitiesAlreadyAdded.TryGetValue(childResource, out childEntity)) { Type entityType = context.GetType().Assembly.GetType(childResource.ResourceType.FullName); childEntity = Activator.CreateInstance(entityType); entitiesAlreadyAdded.Add(childResource, childEntity); PopulateProperties(context, childEntity, childResource, entitiesAlreadyAdded); } SetPropertyValue(entity, resourceProperty.Name, childEntity); } else if (resourceProperty.Kind == ResourcePropertyKind.ResourceSetReference) { List<DSPResource> relatedEntities = (List<DSPResource>)property.Value; object collection = GetPropertyValue(entity, resourceProperty.Name); MethodInfo addMethod = collection.GetType().GetMethod("Add", BindingFlags.Public | BindingFlags.Instance); foreach (DSPResource childResource in relatedEntities) { object childEntity; if (!entitiesAlreadyAdded.TryGetValue(childResource, out childEntity)) { Type entityType = context.GetType().Assembly.GetType(childResource.ResourceType.FullName); childEntity = Activator.CreateInstance(entityType); entitiesAlreadyAdded.Add(childResource, childEntity); PopulateProperties(context, childEntity, childResource, entitiesAlreadyAdded); } addMethod.Invoke(collection, new object[] { childEntity }); } } else if (resourceProperty.Kind == ResourcePropertyKind.ComplexType) { DSPResource complexResource = (DSPResource)property.Value; Type complexType = context.GetType().Assembly.GetType(complexResource.ResourceType.FullName); object complexValue = Activator.CreateInstance(complexType); PopulateProperties(context, complexValue, complexResource, null); SetPropertyValue(entity, resourceProperty.Name, complexValue); } else { // TODO: support collection type properties. throw new Exception("invalid property encountered"); } } }
/// <summary> /// Applies the slug header value to the entity instance /// </summary> /// <param name="slug">slug header value</param> /// <param name="entity">entity instance to apply the slug value</param> protected override void ApplySlugHeader(string slug, object entity) { DSPResource resource = (DSPResource)entity; ResourceType type = resource.ResourceType; ResourceProperty key = type.KeyProperties.First(); // we only try to set the slug header to the first key property. resource.SetValue(key.Name, StringToPrimitive(slug, key.ResourceType.InstanceType)); }
/// <summary>Gets a value of a property specified by a path to that property.</summary> /// <param name="resource">The resource to read the value from.</param> /// <param name="path">The path to the property to read.</param> /// <returns>The value of the property/</returns> public static object GetPropertyPathValue(this DSPResource resource, string path) { if (string.IsNullOrEmpty(path)) { return(resource); } return(GetPropertyPathValueOnResource(resource, path.Split('/'), 0)); }
private static void PopulateContextWithDefaultData(Type contextType, DSPContext dspContext, DSPDataProviderKind providerKind) { Assert.IsTrue(providerKind == DSPDataProviderKind.EF || providerKind == DSPDataProviderKind.Reflection, "expecting only EF and reflection provider"); Dictionary<DSPResource, object> entitiesAlreadyAdded = new Dictionary<DSPResource, object>(); // push all the data to the context. // create a new instance of the context var context = Activator.CreateInstance(contextType); // Clear the database if the context is EF context if (providerKind == DSPDataProviderKind.EF) { if (((DbContext)context).Database.Exists()) { ((DbContext)context).Database.Delete(); } } foreach (var set in dspContext.EntitySets) { string setName = set.Key; List<object> entities = set.Value; foreach (var entity in entities) { DSPResource resource = (DSPResource)entity; if (!entitiesAlreadyAdded.ContainsKey(resource)) { Type entityType = contextType.Assembly.GetType(resource.ResourceType.FullName); var entityInstance = Activator.CreateInstance(entityType); if (providerKind == DSPDataProviderKind.EF) { ((DbContext)context).Set(entityType).Add(entityInstance); } else { IList list = (IList)context.GetType().GetField("_" + setName, BindingFlags.Public | BindingFlags.Static).GetValue(context); list.Add(entityInstance); } entitiesAlreadyAdded.Add(resource, entityInstance); PopulateProperties(context, entityInstance, resource, entitiesAlreadyAdded); } else if (providerKind == DSPDataProviderKind.Reflection) { // Since in reflection provider, adding to the collection does not add to the top level set, adding it explicitly now. IList list = (IList)context.GetType().GetField("_" + setName, BindingFlags.Public | BindingFlags.Static).GetValue(context); list.Add(entitiesAlreadyAdded[resource]); } } } if (providerKind == DSPDataProviderKind.EF) { ((DbContext)context).SaveChanges(); } }
private static object GetPropertyPathValueOnResource(object source, string[] path, int index) { if (index >= path.Length) { return(source); } DSPResource resource = (DSPResource)source; return(GetPropertyPathValueOnResource(resource.GetValue(path[index]), path, index + 1)); }
/// <summary>Validates that the <paramref name="resource"/> is a <see cref="DSPResource"/>.</summary> /// <param name="resource">The resource instance to validate.</param> /// <returns>The resource instance casted to <see cref="DSPResource"/>.</returns> public static DSPResource ValidateDSPResource(object resource) { DSPResource dspResource = resource as DSPResource; if (resource != null && dspResource == null) { throw new ArgumentException("The specified resource is not a DSPResource. That is not supported by this provider."); } return(dspResource); }
/// <summary>Gets a list of all open properties for the specified resource.</summary> /// <param name="target">The target resource to get open properties from.</param> /// <returns>Enumerable of pairs, where the Key is the name of the open property and the Value is the value if that property.</returns> /// <remarks>This method should only return open properties. Properties declared in metadata for this resource's resource type /// must not be returned by this method. /// Properties can have null values. The type of the property is determined from the returned object, only primitive types are supported for now.</remarks> public IEnumerable <KeyValuePair <string, object> > GetOpenPropertyValues(object target) { DSPResource entity = target as DSPResource; if (entity != null) { return(entity.GetOpenPropertyValues()); } else { throw new NotSupportedException("Unrecognized resource type."); } }
/// <summary>Gets a value of a declared property for a resource.</summary> /// <param name="target">The target resource to get a value of the property from.</param> /// <param name="resourceProperty">The name of the property to get.</param> /// <returns>The value of the property.</returns> /// <remarks>The returned value's type should match the type declared in the resource's resource type.</remarks> public object GetPropertyValue(object target, ResourceProperty resourceProperty) { DSPResource entity = target as DSPResource; if (entity != null) { return(entity.GetValue(resourceProperty.Name)); } else { throw new NotSupportedException("Unrecognized resource type."); } }
/// <summary> /// Validates the entity and stream parameters. /// </summary> /// <param name="entity">entity instance.</param> /// <param name="streamProperty">stream info</param> protected override void ValidateEntity(object entity, ResourceProperty streamProperty) { this.ValidateEntity(entity); DSPResource resource = (DSPResource)entity; ResourceType type = resource.ResourceType; if (streamProperty == null && !type.IsMediaLinkEntry) { throw new InvalidOperationException("The specified entity is not an MLE."); } if (streamProperty != null && type.Properties.SingleOrDefault(s => s.Kind == ResourcePropertyKind.Stream && s.Name == streamProperty.Name) == null) { throw new InvalidOperationException("The specified streamName does not exist on the entity."); } }
/// <summary> /// Resets the value of the given resource to its default value /// </summary> /// <param name="resource">resource whose value needs to be reset</param> /// <returns>same resource with its value reset</returns> /// <remarks>This method should reset resource properties to their default values. /// The resource is specfied by its resource "handle" by the <paramref name="resource"/>. /// The method can choose to modify the existing resource or create a new one and it should return a resource "handle" /// to the resource which has its properties with default values. If it chooses to return a new resource it must also /// replace that old resource with the new one in its resource set and all the references which may point to it. /// The returned resource must have the same identity as the one on the input. That means all its key properties must have the same value. /// All changes made by this method should be creates as pending until SaveChanges is called which will commit them (or if it's not called and ClearChanges /// is called instead they should be discarded).</remarks> public virtual object ResetResource(object resource) { DSPResource dspResource = ValidateDSPResource(resource); this.pendingChanges.Add(() => { foreach (var resourceProperty in dspResource.ResourceType.Properties) { // We must only reset values of non-key properties, the key properties must be persited (to maintain the identity of the resource instance) if ((resourceProperty.Kind & ResourcePropertyKind.Key) != ResourcePropertyKind.Key) { dspResource.SetValue(resourceProperty.Name, null); } } }); return(resource); }
/// <summary> /// Passes the etag value for the given resource. /// </summary> /// <param name="resourceCookie">cookie representing the resource.</param> /// <param name="checkForEquality">true if we need to compare the property values for equality. If false, then we need to compare values for non-equality.</param> /// <param name="concurrencyValues">list of the etag property names and its corresponding values.</param> public void SetConcurrencyValues(object resourceCookie, bool?checkForEquality, IEnumerable <KeyValuePair <string, object> > concurrencyValues) { DSPResource dspTargetResource = ValidateDSPResource(resourceCookie); // This implementation does pretty much exactly the same thing as the product if no IDataServiceUpdateProvider is implemented // Especially this throws the same exceptions/status codes as the product. if (checkForEquality == null) { throw new DataServiceException(400, "Update operation to resource of type '" + dspTargetResource.ResourceType.FullName + "' is missing an If-Match header even though the resource has an ETag."); } foreach (var concurrencyValue in concurrencyValues) { if (!concurrencyValue.Value.Equals(dspTargetResource.GetValue(concurrencyValue.Key))) { throw new DataServiceException(412, "Wrong If-Match header value for property '" + concurrencyValue.Key + "'. The header value is '" + concurrencyValue.Value.ToString() + "', but the expected value is '" + (dspTargetResource.GetValue(concurrencyValue.Key) ?? "null").ToString() + "'."); } } }
/// <summary> /// Gets the value of the given property on the target object /// </summary> /// <param name="targetResource">target object which defines the property</param> /// <param name="propertyName">name of the property whose value needs to be updated</param> /// <returns>the value of the property for the given target resource</returns> /// <remarks>The method gets a resource "handle" in the <paramref name="targetResource"/> and the name of a resource property /// defined on it and should return the value of that property.</remarks> public virtual object GetValue(object targetResource, string propertyName) { DSPResource dspTargetResource = ValidateDSPResource(targetResource); // First try to get the value from the modified properties Dictionary <string, object> propertiesModified; if (this.propertyValuesModified.TryGetValue(dspTargetResource, out propertiesModified)) { object propertyValue; if (propertiesModified.TryGetValue(propertyName, out propertyValue)) { return(propertyValue); } } // Only if the property has no been modified yet, return the value from the actual resource. return(dspTargetResource.GetValue(propertyName)); }
/// <summary> /// Creates the resource of the given type and belonging to the given container /// </summary> /// <param name="containerName">container name to which the resource needs to be added</param> /// <param name="fullTypeName">full type name i.e. Namespace qualified type name of the resource</param> /// <returns>object representing a resource of given type and belonging to the given container</returns> /// <remarks>The method should create a new instance of the resource type specified by the <paramref name="fullTypeName"/> /// and add it to the resource set specified by the <paramref name="containerName"/>. /// The method should then return the "handle" to the resource just created. /// All properties of the new resource should have their default values. /// This method is called in two slightly different cases: /// - entity resource creation - in this case the <paramref name="containerName"/> specifies the name of the resource set /// the newly created entity should be added to and the <paramref name="fullTypeName"/> is the FullName of the resource type representing /// entity type. The method should create new instance of the type and add it to the resource set. /// - complex resource creation - in this case the <paramref name="containerName"/> is null and the <paramref name="fullTypeName"/> /// specified the FullName of the resource type representing a complex type. The method should just create new instance of the type /// and return it. Later the <see cref="SetValue"/> will be called to set the complex type instance returned as a value of some /// complex property. /// All changes made by this method should be creates as pending until SaveChanges is called which will commit them (or if it's not called and ClearChanges /// is called instead they should be discarded).</remarks> public virtual object CreateResource(string containerName, string fullTypeName) { ResourceType resourceType; if (!this.metadata.TryResolveResourceType(fullTypeName, out resourceType)) { throw new ArgumentException("Unknown resource type '" + fullTypeName + "'."); } // Create new instance of the DSPResource (this will create empty property bag, which is the same as all properties having default values) DSPResource newResource = (DSPResource)Activator.CreateInstance(resourceType.InstanceType, resourceType); if (containerName != null) { // We're creating an entity and should add it to the resource set // This check here is just for documentation, the method should never be called with non-entity type in this case. if (resourceType.ResourceTypeKind != ResourceTypeKind.EntityType) { throw new ArgumentException("The specified resource type '" + fullTypeName + "' is not an entity type, but resource set was specified."); } IList <object> resourceSetList = this.dataContext.GetResourceSetEntities(containerName); // And register pending change to add the resource to the resource set list this.pendingChanges.Add(() => { resourceSetList.Add(newResource); }); } else { // We're creating a complex type instance, so no additional operation is needed. // This check here is just for documentation the method should never be called with non-complex type in this case. if (resourceType.ResourceTypeKind != ResourceTypeKind.ComplexType) { throw new ArgumentException("The specified resource type '" + fullTypeName + "' is not a complex type."); } } // The method should return the resource "handle", we don't have handles so we return the resource itself directly. return(newResource); }
/// <summary> /// Adds the given value to the collection /// </summary> /// <param name="targetResource">target object which defines the property</param> /// <param name="propertyName">name of the property whose value needs to be updated</param> /// <param name="resourceToBeAdded">value of the property which needs to be added</param> /// <remarks>Adds resource instance <paramref name="resourceToBeAdded"/> into a resource reference set /// <paramref name="propertyName"/> on resource <paramref name="targetResource"/>. /// Both resources, that is <paramref name="targetResource"/> and <paramref name="resourceToBeAdded"/>, are specified /// in the parameters as the resource "handle". /// All changes made by this method should be creates as pending until SaveChanges is called which will commit them (or if it's not called and ClearChanges /// is called instead they should be discarded).</remarks> public virtual void AddReferenceToCollection(object targetResource, string propertyName, object resourceToBeAdded) { // We don't use resource "handles" so both resources passed in as parameters are the real resource instances. DSPResource dspTargetResource = ValidateDSPResource(targetResource); DSPResource dspResourceToBeAdded = ValidateDSPResource(resourceToBeAdded); // All resource set reference properties must be of type IList<DSPResource> (assumption of this provider) // Note that we don't support bi-directional relationships so we only handle the one resource set reference property in isolation. IList <DSPResource> list = dspTargetResource.GetValue(propertyName) as IList <DSPResource>; if (list == null) { throw new ArgumentException("The value of the property '" + propertyName + "' does not implement IList<DSPResource>, which is a requirement for resource set reference property."); } this.pendingChanges.Add(() => { list.Add(dspResourceToBeAdded); }); }
/// <summary> /// Validates the entity. /// </summary> /// <param name="entity">entity instance.</param> protected override void ValidateEntity(object entity) { DSPResource resource = entity as DSPResource; if (entity == null) { throw new NotSupportedException("Only entities of DSPResource type are currently supported."); } ResourceType type = resource.ResourceType; if (type.ResourceTypeKind != ResourceTypeKind.EntityType) { throw new InvalidOperationException("EntityType expected"); } if (!type.IsMediaLinkEntry && !type.Properties.Any(p => p.Kind == ResourcePropertyKind.Stream)) { throw new InvalidOperationException("The given entity is not an MLE and has no named streams."); } }
/// <summary> /// Sets the value of the given property on the target object /// </summary> /// <param name="targetResource">target object which defines the property</param> /// <param name="propertyName">name of the property whose value needs to be updated</param> /// <param name="propertyValue">value of the property</param> /// <remarks>This method should pend a change which will set a resource property with name <paramref name="propertyName"/> /// to value specified by <paramref name="propertyValue"/> on the resource specified by the resource "handle" <paramref name="targetResource"/>. /// All changes made by this method should be creates as pending until SaveChanges is called which will commit them (or if it's not called and ClearChanges /// is called instead they should be discarded).</remarks> public virtual void SetValue(object targetResource, string propertyName, object propertyValue) { DSPResource dspTargetResource = ValidateDSPResource(targetResource); // Note that we rely on the DSPResource.SetValue implementation to correctly deal with collections. // Add a pending change to modify the value of the property this.pendingChanges.Add(() => { dspTargetResource.SetValue(propertyName, propertyValue); }); // And remember the new value Dictionary <string, object> propertiesModified; if (!this.propertyValuesModified.TryGetValue(dspTargetResource, out propertiesModified)) { propertiesModified = new Dictionary <string, object>(); this.propertyValuesModified[dspTargetResource] = propertiesModified; } propertiesModified[propertyName] = propertyValue; }
/// <summary>Creates a server resource from the specified client resource</summary> /// <param name="clientResource">The client resource instance.</param> /// <param name="createCollection">Optional func to create a new collection instance on the server. /// The first parameter is the collection resource type, the second is enumeration of server items to be added to the collection.</param> /// <param name="clientInstanceToResourceType">Func to resolve client resource to a server resource type.</param> /// <returns>The server resource instance.</returns> public static DSPResource CreateServerResourceFromClientResource( object clientResource, Func <providers.CollectionResourceType, IEnumerable <object>, object> createCollection, Func <object, providers.ResourceType> clientInstanceToResourceType) { providers.ResourceType resourceType = clientInstanceToResourceType(clientResource); DSPResource resource = new DSPResource(resourceType); IEnumerable <PropertyInfo> properties = clientResource.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); foreach (var property in properties) { var sameProperties = properties.Where(p => p.Name == property.Name).ToList(); sameProperties.Sort((p1, p2) => p1.DeclaringType.IsAssignableFrom(p2.DeclaringType) ? 1 : -1); if (sameProperties[0] == property) { object value = property.GetValue(clientResource, null); providers.ResourceProperty resourceProperty = resourceType == null ? null : resourceType.Properties.SingleOrDefault(p => p.Name == property.Name); resource.SetRawValue(property.Name, CreateServerValueFromClientValue(value, resourceProperty == null ? null : resourceProperty.ResourceType, createCollection, clientInstanceToResourceType)); } } return(resource); }
private static DSPResource CreateResource(DSPMetadata metadata, string entityTypeName, int idValue, KeyValuePair<string, object>[] propertyValues, bool useComplexType) { var entityType = metadata.GetResourceType(entityTypeName); DSPResource entity; if (useComplexType) { entity = new DSPResource(entityType); } else { entity = new DSPResource(entityType, propertyValues); } entity.SetValue("ID", idValue); DSPResource resourceForProperties; if (useComplexType) { string complexTypeName = GetComplexTypeName(entityTypeName); var complexType = metadata.GetResourceType(complexTypeName); resourceForProperties = new DSPResource(complexType, propertyValues); entity.SetValue("ComplexProperty", resourceForProperties); } else { resourceForProperties = entity; } return entity; }
/// <summary> /// Writes the properties of a DSPResource. /// </summary> /// <param name="entry">DSPResource instance to serialize.</param> private void WriteProperties(DSPResource entry) { ResourceType type = entry.ResourceType; foreach (KeyValuePair<string, object> property in entry.Properties) { ResourceProperty resourceProperty = type.Properties.FirstOrDefault(p => p.Name == property.Key); this.BeginWriteProperty(resourceProperty); this.WriteValue(resourceProperty.ResourceType, property.Value); this.EndWriteProperty(); } }
/// <summary> /// Serializes a DSPResource entity /// </summary> /// <param name="entity">DSPResource instance to serialize.</param> public void WriteEntity(DSPResource entity) { ResourceType type = entity.ResourceType; if (type.ResourceTypeKind != ResourceTypeKind.EntityType) { throw new NotSupportedException("Only EntityType is currently supported."); } this.StartEntry(entity, true); this.WriteEntryMetadata(entity); this.PreWriteProperties(entity); this.WriteProperties(entity); this.PostWriteProperties(); this.EndEntry(); }
/// <summary> /// Serializes the specified entity resource /// </summary> /// <param name="entity">The entity resource to serialize.</param> /// <param name="format">The format in which to serialize.</param> /// <param name="output">The stream to serialize to.</param> /// <param name="encoding">The text encoding to use for the serialization.</param> public static void WriteEntity(DSPResource entity, DSPResourceSerializerFormat format, Stream output, Encoding encoding) { CreateSerializerAndRun(format, output, encoding, (serializer) => { serializer.WriteEntity(entity); }); }
public void AllowRedefiningConcurrencyTokenOnDerivedType() { var metadataProvider = new DSPMetadata("DefaultContainer", "Default"); var entityType = metadataProvider.AddEntityType("EntityType", null, null, false /*isAbstract*/); metadataProvider.AddKeyProperty(entityType, "ID", typeof(int)); metadataProvider.AddPrimitiveProperty(entityType, "LastUpdatedAuthor", typeof(string), true /*eTag*/); var derivedType = metadataProvider.AddEntityType("DerivedType", null, entityType, false /*isAbstract*/); metadataProvider.AddPrimitiveProperty(derivedType, "LastModifiedAuthor", typeof(string), true /*eTag*/); metadataProvider.AddResourceSet("Customers", entityType); var wrapper = new DataServiceMetadataProviderWrapper(metadataProvider); DSPResource baseTypeInstance = new DSPResource(entityType); baseTypeInstance.SetValue("ID", 1); baseTypeInstance.SetValue("LastUpdatedAuthor", "Phani"); DSPResource derivedTypeInstance = new DSPResource(derivedType); derivedTypeInstance.SetValue("ID", 1); derivedTypeInstance.SetValue("LastModifiedAuthor", "Raj"); DSPContext dataContext = new DSPContext(); var entities = dataContext.GetResourceSetEntities("Customers"); entities.AddRange(new object[] { baseTypeInstance, derivedTypeInstance }); var service = new DSPUnitTestServiceDefinition(metadataProvider, DSPDataProviderKind.Reflection, dataContext); using (TestWebRequest request = service.CreateForInProcess()) { try { request.StartService(); request.RequestUriString = "/$metadata"; request.SendRequestAndCheckResponse(); } finally { request.StopService(); } } }
protected abstract void StartEntry(DSPResource entry, bool isTopLevel);
protected override void PreWriteProperties(DSPResource entry) { // Do nothing. }
/// <summary> /// Serializes the specified entity resource into a string /// </summary> /// <param name="entity">The entity resource to serialize.</param> /// <param name="format">The format in which to serialize.</param> /// <returns>The entity serialized as a string</returns> public static string WriteEntity(DSPResource entity, DSPResourceSerializerFormat format) { return CreateSerializerAndRunIntoString(format, (serializer) => { serializer.WriteEntity(entity); }); }
internal static DSPServiceDefinition SetUpNamedStreamService() { DSPMetadata metadata = new DSPMetadata("NamedStreamIDSPContainer", "NamedStreamTest"); // entity with streams ResourceType entityWithNamedStreams = metadata.AddEntityType("EntityWithNamedStreams", null, null, false); metadata.AddKeyProperty(entityWithNamedStreams, "ID", typeof(int)); metadata.AddPrimitiveProperty(entityWithNamedStreams, "Name", typeof(string)); ResourceProperty streamInfo1 = new ResourceProperty("Stream1", ResourcePropertyKind.Stream, ResourceType.GetPrimitiveResourceType(typeof(Stream))); entityWithNamedStreams.AddProperty(streamInfo1); ResourceProperty streamInfo2 = new ResourceProperty("Stream2", ResourcePropertyKind.Stream, ResourceType.GetPrimitiveResourceType(typeof(Stream))); entityWithNamedStreams.AddProperty(streamInfo2); // entity1 with streams ResourceType entityWithNamedStreams1 = metadata.AddEntityType("EntityWithNamedStreams1", null, null, false); metadata.AddKeyProperty(entityWithNamedStreams1, "ID", typeof(int)); metadata.AddPrimitiveProperty(entityWithNamedStreams1, "Name", typeof(string)); ResourceProperty refStreamInfo1 = new ResourceProperty("RefStream1", ResourcePropertyKind.Stream, ResourceType.GetPrimitiveResourceType(typeof(Stream))); entityWithNamedStreams1.AddProperty(refStreamInfo1); // entity2 with streams ResourceType entityWithNamedStreams2 = metadata.AddEntityType("EntityWithNamedStreams2", null, null, false); metadata.AddKeyProperty(entityWithNamedStreams2, "ID", typeof(string)); metadata.AddPrimitiveProperty(entityWithNamedStreams2, "Name", typeof(string)); ResourceProperty collectionStreamInfo = new ResourceProperty("ColStream", ResourcePropertyKind.Stream, ResourceType.GetPrimitiveResourceType(typeof(Stream))); entityWithNamedStreams2.AddProperty(collectionStreamInfo); ResourceSet set1 = metadata.AddResourceSet("MySet1", entityWithNamedStreams); ResourceSet set2 = metadata.AddResourceSet("MySet2", entityWithNamedStreams1); ResourceSet set3 = metadata.AddResourceSet("MySet3", entityWithNamedStreams2); // add navigation property to entityWithNamedStreams metadata.AddResourceReferenceProperty(entityWithNamedStreams, "Ref", set2, entityWithNamedStreams1); metadata.AddResourceSetReferenceProperty(entityWithNamedStreams, "Collection", set3, entityWithNamedStreams2); metadata.AddResourceSetReferenceProperty(entityWithNamedStreams2, "Collection1", set2, entityWithNamedStreams1); DSPServiceDefinition service = new DSPServiceDefinition(); service.Metadata = metadata; service.MediaResourceStorage = new DSPMediaResourceStorage(); service.SupportMediaResource = true; service.SupportNamedStream = true; service.ForceVerboseErrors = true; service.PageSizeCustomizer = (config, type) => { config.SetEntitySetPageSize("MySet3", 1); }; // populate data DSPContext context = new DSPContext(); DSPResource entity1 = new DSPResource(entityWithNamedStreams); { context.GetResourceSetEntities("MySet1").Add(entity1); entity1.SetValue("ID", 1); entity1.SetValue("Name", "Foo"); DSPMediaResource namedStream1 = service.MediaResourceStorage.CreateMediaResource(entity1, streamInfo1); namedStream1.ContentType = "image/jpeg"; byte[] data1 = new byte[] { 0, 1, 2, 3, 4 }; namedStream1.GetWriteStream().Write(data1, 0, data1.Length); DSPMediaResource namedStream2 = service.MediaResourceStorage.CreateMediaResource(entity1, streamInfo2); namedStream2.ContentType = "image/jpeg"; byte[] data2 = new byte[] { 0, 1, 2, 3, 4 }; namedStream2.GetWriteStream().Write(data2, 0, data2.Length); } DSPResource entity2 = new DSPResource(entityWithNamedStreams1); { context.GetResourceSetEntities("MySet2").Add(entity2); entity2.SetValue("ID", 3); entity2.SetValue("Name", "Bar"); DSPMediaResource refNamedStream1 = service.MediaResourceStorage.CreateMediaResource(entity2, refStreamInfo1); refNamedStream1.ContentType = "image/jpeg"; byte[] data1 = new byte[] { 0, 1, 2, 3, 4 }; refNamedStream1.GetWriteStream().Write(data1, 0, data1.Length); // set the navigation property entity1.SetValue("Ref", entity2); } { DSPResource entity3 = new DSPResource(entityWithNamedStreams2); context.GetResourceSetEntities("MySet3").Add(entity3); entity3.SetValue("ID", "ABCDE"); entity3.SetValue("Name", "Bar"); DSPMediaResource stream = service.MediaResourceStorage.CreateMediaResource(entity3, collectionStreamInfo); stream.ContentType = "image/jpeg"; byte[] data1 = new byte[] { 0, 1, 2, 3, 4 }; stream.GetWriteStream().Write(data1, 0, data1.Length); entity3.SetValue("Collection1", new List<DSPResource>() { entity2 }); DSPResource entity4 = new DSPResource(entityWithNamedStreams2); context.GetResourceSetEntities("MySet3").Add(entity4); entity4.SetValue("ID", "XYZ"); entity4.SetValue("Name", "Foo"); DSPMediaResource stream1 = service.MediaResourceStorage.CreateMediaResource(entity3, collectionStreamInfo); stream1.ContentType = "image/jpeg"; stream1.GetWriteStream().Write(data1, 0, data1.Length); entity4.SetValue("Collection1", new List<DSPResource>() { entity2 }); entity1.SetValue("Collection", new List<DSPResource>() { entity3, entity4 }); } service.DataSource = context; return service; }
/// <summary> /// Creates a datasource from the given metadata. /// </summary> /// <param name="metadata">The metadata against which the datasource is created.</param> /// <returns>DSPContext representing the data source.</returns> private static DSPContext CreateDataSource(DSPMetadata metadata) { DSPContext context = new DSPContext(); ResourceType customerType = metadata.GetResourceType("CustomerEntity"); DSPResource entity1 = new DSPResource(customerType); entity1.SetValue("ID", 1); entity1.SetValue("Name", "Vineet"); DSPResource entity2 = new DSPResource(customerType); entity2.SetValue("ID", 2); entity2.SetValue("Name", "Jimmy"); context.GetResourceSetEntities("CustomerEntities").Add(entity1); context.GetResourceSetEntities("CustomerEntities").Add(entity2); return context; }
private void PreferHeader_SetupRequest(TestWebRequest request, string httpMethod, string format, XDocument existingItemAtom, DSPResource existingItem, Action<XDocument> modifyInputAtom) { string realHttpMethod = httpMethod; if (realHttpMethod == "POSTMR") { realHttpMethod = "POST"; } request.HttpMethod = realHttpMethod; request.RequestContentType = httpMethod == "POSTMR" ? UnitTestsUtil.MimeTextPlain : format; request.Accept = format; XDocument inputAtom = new XDocument(existingItemAtom); // Remove all nav property links as those are not supported on some operations inputAtom.Root.Elements(UnitTestsUtil.AtomNamespace + "link").Where(e => e.Attribute("rel").Value.Contains("http://docs.oasis-open.org/odata/ns/related/") || e.Attribute("rel").Value.Contains("http://docs.oasis-open.org/odata/ns/relatedlinks/")).Remove(); request.RequestHeaders["Slug"] = null; if (httpMethod == "POST") { inputAtom.Root.Element(UnitTestsUtil.AtomNamespace + "content").Element(UnitTestsUtil.MetadataNamespace + "properties") .Element(UnitTestsUtil.DataNamespace + "ID").Value = "1"; request.IfMatch = null; request.RequestUriString = "/Items"; } else if (httpMethod == "POSTMR") { request.RequestHeaders["Slug"] = "1"; request.IfMatch = null; request.RequestUriString = "/Streams"; } else { request.IfMatch = existingItem.GetETag(); request.RequestUriString = "/Items(0)"; } if (httpMethod == "POSTMR") { request.SetRequestStreamAsText("some text content"); } else { if (modifyInputAtom != null) { modifyInputAtom(inputAtom); } request.SetRequestStreamAsText(inputAtom.ToString()); } }
protected abstract void WriteEntryMetadata(DSPResource entry);
private static DSPContext GetDefaultData(DSPMetadata metadata) { var peopleType = metadata.GetResourceType("PeopleType"); var employeeType = metadata.GetResourceType("EmployeeType"); var managerType = metadata.GetResourceType("ManagerType"); var customerType = metadata.GetResourceType("CustomerType"); var employeeAddressType = metadata.GetResourceType("EmployeeAddressType"); var customerAddressType = metadata.GetResourceType("CustomerAddressType"); #region Default Data for the Model var context = new DSPContext(); DSPResource people1 = new DSPResource(peopleType); people1.SetValue("ID", 1); people1.SetValue("Name", "Foo"); DSPResource andyAddress = new DSPResource(employeeAddressType); andyAddress.SetValue("ID", 1); andyAddress.SetValue("Street", "Andy's address"); andyAddress.SetValue("City", "Sammamish"); andyAddress.SetValue("State", "WA"); DSPResource andy = new DSPResource(managerType); andy.SetValue("ID", 2); andy.SetValue("Name", "Andy"); andy.SetValue("FullName", "Andy Conrad"); andy.SetValue("Address", andyAddress); DSPResource pratikAddress = new DSPResource(employeeAddressType); pratikAddress.SetValue("ID", 2); pratikAddress.SetValue("Street", "pratik's address"); pratikAddress.SetValue("City", "Bothell"); pratikAddress.SetValue("State", "WA"); DSPResource pratik = new DSPResource(employeeType); pratik.SetValue("ID", 3); pratik.SetValue("Name", "Pratik"); pratik.SetValue("FullName", "Pratik Patel"); pratik.SetValue("Manager", andy); pratik.SetValue("Address", pratikAddress); DSPResource jimmyAddress = new DSPResource(employeeAddressType); jimmyAddress.SetValue("ID", 3); jimmyAddress.SetValue("Street", "jimmy's address"); jimmyAddress.SetValue("City", "somewhere in seattle"); jimmyAddress.SetValue("State", "WA"); DSPResource jimmy = new DSPResource(employeeType); jimmy.SetValue("ID", 4); jimmy.SetValue("Name", "Jimmy"); jimmy.SetValue("FullName", "Jian Li"); jimmy.SetValue("Manager", andy); jimmy.SetValue("Address", jimmyAddress); andy.SetValue("DirectReports", new List<DSPResource>() { pratik, jimmy }); DSPResource shyamAddress = new DSPResource(employeeAddressType); shyamAddress.SetValue("ID", 4); shyamAddress.SetValue("Street", "shyam's address"); shyamAddress.SetValue("City", "university district"); shyamAddress.SetValue("State", "WA"); DSPResource shyam = new DSPResource(managerType); shyam.SetValue("ID", 5); shyam.SetValue("Name", "Shyam"); shyam.SetValue("FullName", "Shyam Pather"); shyam.SetValue("Address", shyamAddress); DSPResource marceloAddress = new DSPResource(employeeAddressType); marceloAddress.SetValue("ID", 5); marceloAddress.SetValue("Street", "marcelo's address"); marceloAddress.SetValue("City", "kirkland"); marceloAddress.SetValue("State", "WA"); DSPResource marcelo = new DSPResource(employeeType); marcelo.SetValue("ID", 6); marcelo.SetValue("Name", "Marcelo"); marcelo.SetValue("FullName", "Marcelo Lopez Ruiz"); marcelo.SetValue("Manager", shyam); marcelo.SetValue("Address", marceloAddress); andy.SetValue("Manager", shyam); shyam.SetValue("DirectReports", new List<DSPResource>() { andy, marcelo }); DSPResource customer1Address = new DSPResource(customerAddressType); customer1Address.SetValue("ID", 6); customer1Address.SetValue("Street", "customer1's address"); customer1Address.SetValue("City", "somewhere"); customer1Address.SetValue("State", "WA"); var customer1 = new DSPResource(customerType); customer1.SetValue("ID", 7); customer1.SetValue("FullName", "Customer FullName"); customer1.SetValue("Address", customer1Address); var people = context.GetResourceSetEntities("People"); people.AddRange(new object[] { people1, andy, pratik, jimmy, shyam, marcelo, customer1 }); var addresses = context.GetResourceSetEntities("Addresses"); addresses.AddRange(new object[] { andyAddress, pratikAddress, jimmyAddress, shyamAddress, marceloAddress, customer1Address }); #endregion Default Data for the Model return context; }
private static DSPContext GetDefaultData(DSPMetadata metadata) { var peopleType = metadata.GetResourceType("PeopleType"); var officeType = metadata.GetResourceType("OfficeType"); #region Default Data for the Model var context = new DSPContext(); DSPResource people1 = new DSPResource(peopleType); people1.SetValue("ID", 1); people1.SetValue("Name", "Foo"); people1.SetValue("Body", Encoding.UTF8.GetBytes("a byte array")); people1.SetValue("Age", 23); var office = new DSPResource(officeType); office.SetValue("Building", "Building 18"); office.SetValue("OfficeNumber", 100); people1.SetValue("Office", office); var people = context.GetResourceSetEntities("People"); people.Add( people1 ); #endregion Default Data for the Model return context; }
private static DSPServiceDefinition ModelWithDerivedNavigationProperties() { // Navigation Collection Property: Client - Entity, Server - NonEntity DSPMetadata metadata = new DSPMetadata("ModelWithDerivedNavProperties", "AstoriaUnitTests.Tests.DerivedProperty"); var peopleType = metadata.AddEntityType("Person", null, null, false); metadata.AddKeyProperty(peopleType, "ID", typeof(int)); metadata.AddPrimitiveProperty(peopleType, "Name", typeof(string)); var bestFriendProperty = metadata.AddResourceReferenceProperty(peopleType, "BestFriend", peopleType); var friendsProperty = metadata.AddResourceSetReferenceProperty(peopleType, "Friends", peopleType); var aquaintancesProperty = metadata.AddResourceSetReferenceProperty(peopleType, "Aquaintances", peopleType); var peopleSet = metadata.AddResourceSet("People", peopleType); var officeType = metadata.AddComplexType("Office", null, null, false); metadata.AddPrimitiveProperty(officeType, "Building", typeof(string)); metadata.AddPrimitiveProperty(officeType, "OfficeNumber", typeof(int)); var vacationType = metadata.AddComplexType("Vacation", null, null, false); metadata.AddPrimitiveProperty(vacationType, "Description", typeof(string)); metadata.AddPrimitiveProperty(vacationType, "StartDate", typeof(DateTimeOffset)); metadata.AddPrimitiveProperty(vacationType, "EndDate", typeof(DateTimeOffset)); var employeeType = metadata.AddEntityType("Employee", null, peopleType, false); metadata.AddCollectionProperty(employeeType, "Vacations", vacationType); metadata.AddComplexProperty(employeeType, "Office", officeType); metadata.AddCollectionProperty(employeeType, "Skills", ResourceType.GetPrimitiveResourceType(typeof(string))); metadata.AddNamedStreamProperty(employeeType, "Photo"); var managerType = metadata.AddEntityType("PeopleManager", null, employeeType, false); var drProperty = metadata.AddResourceSetReferenceProperty(managerType, "DirectReports", employeeType); var managerProperty = metadata.AddResourceReferenceProperty(employeeType, "Manager", managerType); var colleaguesProperty = metadata.AddResourceSetReferenceProperty(employeeType, "Colleagues", employeeType); metadata.AddResourceAssociationSet(new ResourceAssociationSet( "Manager_DirectReports", new ResourceAssociationSetEnd(peopleSet, employeeType, managerProperty), new ResourceAssociationSetEnd(peopleSet, managerType, drProperty))); metadata.AddResourceAssociationSet(new ResourceAssociationSet( "BestFriend", new ResourceAssociationSetEnd(peopleSet, peopleType, bestFriendProperty), new ResourceAssociationSetEnd(peopleSet, peopleType, null))); metadata.AddResourceAssociationSet(new ResourceAssociationSet( "Friends", new ResourceAssociationSetEnd(peopleSet, peopleType, friendsProperty), new ResourceAssociationSetEnd(peopleSet, peopleType, null))); metadata.AddResourceAssociationSet(new ResourceAssociationSet( "Colleagues", new ResourceAssociationSetEnd(peopleSet, employeeType, colleaguesProperty), new ResourceAssociationSetEnd(peopleSet, employeeType, null))); metadata.AddResourceAssociationSet(new ResourceAssociationSet( "Aquaintances", new ResourceAssociationSetEnd(peopleSet, peopleType, aquaintancesProperty), new ResourceAssociationSetEnd(peopleSet, peopleType, null))); metadata.SetReadOnly(); DSPContext context = new DSPContext(); DSPResource people1 = new DSPResource(peopleType); people1.SetValue("ID", 1); people1.SetValue("Name", "Foo"); people1.SetValue("Friends", new List<DSPResource>()); DSPResource thanksgivingVacation = new DSPResource(vacationType); thanksgivingVacation.SetValue("Description", "Thanksgiving"); thanksgivingVacation.SetValue("StartDate", new DateTime(2011, 11, 19)); thanksgivingVacation.SetValue("EndDate", new DateTime(2011, 11, 27)); DSPResource christmasVacation = new DSPResource(vacationType); christmasVacation.SetValue("Description", "Christmas"); christmasVacation.SetValue("StartDate", new DateTime(2011, 12, 24)); christmasVacation.SetValue("EndDate", new DateTime(2012, 1, 2)); DSPResource andy = new DSPResource(managerType); andy.SetValue("ID", 2); andy.SetValue("Name", "Andy"); andy.SetValue("Vacations", new List<DSPResource>() { thanksgivingVacation, christmasVacation }); var office = new DSPResource(officeType); office.SetValue("Building", "Building 18"); office.SetValue("OfficeNumber", 100); andy.SetValue("Office", office); andy.SetValue("Skills", new List<string>() { "CSharp", "VB", "SQL" }); andy.SetValue("Friends", new List<DSPResource>() { people1 }); andy.SetValue("Aquaintences", new List<DSPResource>()); DSPResource pratik = new DSPResource(employeeType); pratik.SetValue("ID", 3); pratik.SetValue("Name", "Pratik"); pratik.SetValue("Manager", andy); pratik.SetValue("Vacations", new List<DSPResource>() { christmasVacation }); office = new DSPResource(officeType); office.SetValue("Building", "Building 18"); office.SetValue("OfficeNumber", 101); pratik.SetValue("Office", office); pratik.SetValue("Skills", new List<string>() { "CSharp", "VB", "SQL" }); pratik.SetValue("Friends", new List<DSPResource>() { people1 }); pratik.SetValue("Aquaintences", new List<DSPResource>()); DSPResource jimmy = new DSPResource(employeeType); jimmy.SetValue("ID", 4); jimmy.SetValue("Name", "Jimmy"); jimmy.SetValue("Manager", andy); jimmy.SetValue("Vacations", new List<DSPResource>() { thanksgivingVacation, christmasVacation }); office = new DSPResource(officeType); office.SetValue("Building", "Building 18"); office.SetValue("OfficeNumber", 102); jimmy.SetValue("Office", office); jimmy.SetValue("Skills", new List<string>() { "CSharp", "SQL" }); jimmy.SetValue("Friends", new List<DSPResource>() { people1 }); jimmy.SetValue("Aquaintences", new List<DSPResource>()); andy.SetValue("DirectReports", new List<DSPResource>() { pratik, jimmy }); DSPResource shyam = new DSPResource(managerType); shyam.SetValue("ID", 5); shyam.SetValue("Name", "Shyam"); shyam.SetValue("Manager", shyam); shyam.SetValue("Vacations", new List<DSPResource>() { thanksgivingVacation, christmasVacation }); office = new DSPResource(officeType); office.SetValue("Building", "Building 18"); office.SetValue("OfficeNumber", 103); shyam.SetValue("Office", office); shyam.SetValue("Skills", new List<string>()); shyam.SetValue("Friends", new List<DSPResource>() { people1 }); shyam.SetValue("Aquaintences", new List<DSPResource>()); DSPResource marcelo = new DSPResource(employeeType); marcelo.SetValue("ID", 6); marcelo.SetValue("Name", "Marcelo"); marcelo.SetValue("Manager", shyam); marcelo.SetValue("Vacations", new List<DSPResource>()); office = new DSPResource(officeType); office.SetValue("Building", "Building 18"); office.SetValue("OfficeNumber", 104); marcelo.SetValue("Office", office); marcelo.SetValue("Skills", new List<string>() { "CSharp", "VB", "SQL" }); marcelo.SetValue("Friends", new List<DSPResource>() { people1 }); marcelo.SetValue("Aquaintences", new List<DSPResource>()); andy.SetValue("Manager", shyam); shyam.SetValue("DirectReports", new List<DSPResource>() { andy, marcelo }); pratik.SetValue("BestFriend", andy); andy.SetValue("BestFriend", shyam); shyam.SetValue("BestFriend", marcelo); marcelo.SetValue("BestFriend", jimmy); jimmy.SetValue("BestFriend", people1); people1.SetValue("BestFriend", pratik); andy.SetValue("Colleagues", new List<DSPResource>() { marcelo }); pratik.SetValue("Colleagues", new List<DSPResource>() { jimmy }); jimmy.SetValue("Colleagues", new List<DSPResource>() { pratik }); marcelo.SetValue("Colleagues", new List<DSPResource>() { andy }); shyam.SetValue("Colleagues", new List<DSPResource>()); people1.SetValue("Aquaintances", new List<DSPResource>() { pratik, andy, jimmy, shyam, marcelo }); var people = context.GetResourceSetEntities("People"); people.Add(people1); people.Add(andy); people.Add(pratik); people.Add(jimmy); people.Add(shyam); people.Add(marcelo); DSPServiceDefinition service = new DSPServiceDefinition() { Metadata = metadata, CreateDataSource = (m) => context, ForceVerboseErrors = true, MediaResourceStorage = new DSPMediaResourceStorage(), SupportNamedStream = true, Writable = true, DataServiceBehavior = new OpenWebDataServiceDefinition.OpenWebDataServiceBehavior() { IncludeRelationshipLinksInResponse = true }, }; return service; }
private DSPUnitTestServiceDefinition CreateTestService(bool openType = false) { DSPMetadata metadata = new DSPMetadata("SpatialQueryTests", "AstoriaUnitTests.Tests"); var entityType = metadata.AddEntityType("SpatialEntity", null, null, false); metadata.AddKeyProperty(entityType, "ID", typeof(int)); entityType.IsOpenType = openType; if (!openType) { metadata.AddPrimitiveProperty(entityType, "Geography", typeof(Geography)); metadata.AddPrimitiveProperty(entityType, "Point", typeof(GeographyPoint)); metadata.AddPrimitiveProperty(entityType, "Point2", typeof(GeographyPoint)); metadata.AddPrimitiveProperty(entityType, "LineString", typeof(GeographyLineString)); metadata.AddPrimitiveProperty(entityType, "Polygon", typeof(GeographyPolygon)); metadata.AddPrimitiveProperty(entityType, "GeographyCollection", typeof(GeographyCollection)); metadata.AddPrimitiveProperty(entityType, "MultiPoint", typeof(GeographyMultiPoint)); metadata.AddPrimitiveProperty(entityType, "MultiLineString", typeof(GeographyMultiLineString)); metadata.AddPrimitiveProperty(entityType, "MultiPolygon", typeof(GeographyMultiPolygon)); metadata.AddPrimitiveProperty(entityType, "Geometry", typeof(Geometry)); metadata.AddPrimitiveProperty(entityType, "GeometryPoint", typeof(GeometryPoint)); metadata.AddPrimitiveProperty(entityType, "GeometryPoint2", typeof(GeometryPoint)); metadata.AddPrimitiveProperty(entityType, "GeometryLineString", typeof(GeometryLineString)); metadata.AddPrimitiveProperty(entityType, "GeometryPolygon", typeof(GeometryPolygon)); metadata.AddPrimitiveProperty(entityType, "GeometryCollection", typeof(GeometryCollection)); metadata.AddPrimitiveProperty(entityType, "GeometryMultiPoint", typeof(GeometryMultiPoint)); metadata.AddPrimitiveProperty(entityType, "GeometryMultiLineString", typeof(GeometryMultiLineString)); metadata.AddPrimitiveProperty(entityType, "GeometryMultiPolygon", typeof(GeometryMultiPolygon)); } metadata.AddCollectionProperty(entityType, "CollectionOfPoints", typeof(GeographyPoint)); metadata.AddCollectionProperty(entityType, "GeometryCollectionOfPoints", typeof(GeometryPoint)); metadata.AddPrimitiveProperty(entityType, "GeographyNull", typeof(Geography)); metadata.AddPrimitiveProperty(entityType, "GeometryNull", typeof(Geometry)); metadata.AddResourceSet("Spatials", entityType); metadata.SetReadOnly(); DSPContext context = new DSPContext(); var set = context.GetResourceSetEntities("Spatials"); for (int i = 0; i < 3; ++i) { DSPResource spatialEntity = new DSPResource(entityType); spatialEntity.SetValue("ID", i); spatialEntity.SetValue("Geography", GeographyFactory.Point(32.0 - i, -100.0).Build()); spatialEntity.SetValue("Point", GeographyFactory.Point(33.1 - i, -110.0).Build()); spatialEntity.SetValue("Point2", GeographyFactory.Point(32.1 - i, -110.0).Build()); spatialEntity.SetValue("LineString", GeographyFactory.LineString(33.1 - i, -110.0).LineTo(35.97 - i, -110).Build()); spatialEntity.SetValue("Polygon", GeographyFactory.Polygon().Ring(33.1 - i, -110.0).LineTo(35.97 - i, -110.15).LineTo(11.45 - i, 87.75).Ring(35.97 - i, -110).LineTo(36.97 - i, -110.15).LineTo(45.23 - i, 23.18).Build()); spatialEntity.SetValue("GeographyCollection", GeographyFactory.Collection().Point(-19.99 - i, -12.0).Build()); spatialEntity.SetValue("MultiPoint", GeographyFactory.MultiPoint().Point(10.2 - i, 11.2).Point(11.9 - i, 11.6).Build()); spatialEntity.SetValue("MultiLineString", GeographyFactory.MultiLineString().LineString(10.2 - i, 11.2).LineTo(11.9 - i, 11.6).LineString(16.2 - i, 17.2).LineTo(18.9 - i, 19.6).Build()); spatialEntity.SetValue("MultiPolygon", GeographyFactory.MultiPolygon().Polygon().Ring(10.2 - i, 11.2).LineTo(11.9 - i, 11.6).LineTo(11.45 - i, 87.75).Ring(16.2 - i, 17.2).LineTo(18.9 - i, 19.6).LineTo(11.45 - i, 87.75).Build()); spatialEntity.SetValue("CollectionOfPoints", new List<GeographyPoint>() { GeographyFactory.Point(10.2, 99.5), GeographyFactory.Point(11.2, 100.5) }); spatialEntity.SetValue("Geometry", GeometryFactory.Point(32.0 - i, -10.0).Build()); spatialEntity.SetValue("GeometryPoint", GeometryFactory.Point(33.1 - i, -11.0).Build()); spatialEntity.SetValue("GeometryPoint2", GeometryFactory.Point(32.1 - i, -11.0).Build()); spatialEntity.SetValue("GeometryLineString", GeometryFactory.LineString(33.1 - i, -11.5).LineTo(35.97 - i, -11).Build()); spatialEntity.SetValue("GeometryPolygon", GeometryFactory.Polygon().Ring(33.1 - i, -13.6).LineTo(35.97 - i, -11.15).LineTo(11.45 - i, 87.75).Ring(35.97 - i, -11).LineTo(36.97 - i, -11.15).LineTo(45.23 - i, 23.18).Build()); spatialEntity.SetValue("GeometryCollection", GeometryFactory.Collection().Point(-19.99 - i, -12.0).Build()); spatialEntity.SetValue("GeometryMultiPoint", GeometryFactory.MultiPoint().Point(10.2 - i, 11.2).Point(11.9 - i, 11.6).Build()); spatialEntity.SetValue("GeometryMultiLineString", GeometryFactory.MultiLineString().LineString(10.2 - i, 11.2).LineTo(11.9 - i, 11.6).LineString(16.2 - i, 17.2).LineTo(18.9 - i, 19.6).Build()); spatialEntity.SetValue("GeometryMultiPolygon", GeometryFactory.MultiPolygon().Polygon().Ring(10.2 - i, 11.2).LineTo(11.9 - i, 11.6).LineTo(11.45 - i, 87.75).Ring(16.2 - i, 17.2).LineTo(18.9 - i, 19.6).LineTo(11.45 - i, 87.75).Build()); spatialEntity.SetValue("GeometryCollectionOfPoints", new List<GeometryPoint>() { GeometryFactory.Point(10.2, 99.5), GeometryFactory.Point(11.2, 100.5) }); spatialEntity.SetValue("GeographyNull", null); spatialEntity.SetValue("GeometryNull", null); set.Add(spatialEntity); } var service = new DSPUnitTestServiceDefinition(metadata, DSPDataProviderKind.CustomProvider, context); service.DataServiceBehavior.AcceptSpatialLiteralsInQuery = true; service.Writable = true; return service; }
private static void PopulateResourceSet(DSPContext context, DSPResource resource) { string resourceSetName = GetResourceSetName(resource.ResourceType.Name); var resourceSet = context.GetResourceSetEntities(resourceSetName); resourceSet.AddRange(new object[] { resource }); }
protected override void StartEntry(DSPResource entry, bool isTopLevel) { // { this.writer.StartObjectScope(); }
protected abstract void PreWriteProperties(DSPResource entry);
/// <summary> /// Write metadata information for the entry. /// </summary> /// <param name="entry">Entry to write metadata for.</param> protected override void WriteEntryMetadata(DSPResource entry) { Debug.Assert(entry != null, "entry != null"); // __metadata : { type: "Type" } if (entry.ResourceType != null) { this.writer.WriteName(JsonMetadataString); this.writer.StartObjectScope(); this.writer.WriteName(JsonTypeString); this.writer.WriteValue(entry.ResourceType.FullName); this.writer.EndScope(); } }
public void PreferHeader_UnrelatedRequests() { DSPMetadata metadata = PreferHeader_CreateMetadata(); var item = new DSPSelfmodifyingResource(metadata.GetResourceType("Item")); item.SetRawValue("ID", 0); item.SetRawValue("ETagProperty", 0); item.SetRawValue("Self", item); var collection = new DSPResource(metadata.GetResourceType("Collection")); collection.SetRawValue("ID", 0); collection.SetRawValue("CollectionProperty", new List<int>() { 1, 2, 3 }); var stream = new DSPSelfmodifyingResource(metadata.GetResourceType("Stream")); stream.SetRawValue("ID", 42); var namedStream = new DSPSelfmodifyingResource(metadata.GetResourceType("NamedStream")); namedStream.SetRawValue("ID", 42); DSPServiceDefinition service = PreferHeader_CreateService(metadata, item, collection, stream, namedStream); service.DataServiceBehavior.MaxProtocolVersion = ODataProtocolVersion.V4; var entityReferencePayload = new XElement(UnitTestsUtil.MetadataNamespace + "ref"); entityReferencePayload.SetAttributeValue("id", "/Items(0)"); var testCases = new[] { new { HttpMethod = "GET", RequestUri = "/Items", Payload = "", ContentType = "" }, new { HttpMethod = "GET", RequestUri = "/Collection", Payload = "", ContentType = "" }, new { HttpMethod = "GET", RequestUri = "/$metadata", Payload = "", ContentType = "" }, new { HttpMethod = "GET", RequestUri = "/Items/$count", Payload = "", ContentType = "" }, new { HttpMethod = "GET", RequestUri = "/Items(0)/Self/$ref", Payload = "", ContentType = "" }, new { HttpMethod = "DELETE", RequestUri = "/Collection(0)/Description/$value", Payload = "", ContentType = "" }, new { HttpMethod = "PUT", RequestUri = "/Items(0)/Self/$ref", Payload = entityReferencePayload.ToString(), ContentType = UnitTestsUtil.MimeApplicationXml }, new { // GET MR HttpMethod = "GET", RequestUri = "/Streams(42)/$value", Payload = "", ContentType = "" }, new { // GET named stream HttpMethod = "GET", RequestUri = "/NamedStreams(42)/NamedStream1", Payload = "", ContentType = "" }, new { // PUT named stream HttpMethod = "PUT", RequestUri = "/NamedStreams(42)/NamedStream1", Payload = "another text file", ContentType = UnitTestsUtil.MimeTextPlain }, }; using (TestWebRequest request = service.CreateForInProcess()) { TestUtil.RunCombinations( testCases, new string[] { null, "return=representation", "return=minimal" }, (testCase, preferHeader) => { service.ClearChanges(); request.HttpMethod = testCase.HttpMethod; request.RequestUriString = testCase.RequestUri; request.RequestHeaders["Prefer"] = preferHeader; request.RequestVersion = "4.0;"; request.RequestMaxVersion = "4.0;"; request.RequestContentType = string.IsNullOrEmpty(testCase.ContentType) ? null : testCase.ContentType; string payload = testCase.Payload; if (!string.IsNullOrEmpty(payload) && payload.StartsWith("[")) { int i = payload.IndexOf("]"); string header = payload.Substring(1, i - 1); string[] headervalue = header.Split(':'); request.RequestHeaders[headervalue[0]] = headervalue[1]; payload = payload.Substring(i + 1); } if (!string.IsNullOrEmpty(payload)) { request.SetRequestStreamAsText(payload); } request.SendRequest(); string preferApplied; request.ResponseHeaders.TryGetValue("Preference-Applied", out preferApplied); Assert.IsNull(preferApplied, "No Preference-Applied header should be present on the response."); }); } }
protected override void StartEntry(DSPResource entry, bool isTopLevel) { this.writer.WriteStartElement(AtomEntryElementName, UnitTestsUtil.AtomNamespace.NamespaceName); if (isTopLevel) { this.WriteDefaultNamespaces(); } }
protected override void WriteEntryMetadata(DSPResource entry) { // <category term="type" scheme="odatascheme"/> this.writer.WriteStartElement( AtomCategoryElementName, UnitTestsUtil.AtomNamespace.NamespaceName); this.writer.WriteAttributeString( AtomCategoryTermAttributeName, entry.ResourceType.FullName); this.writer.WriteAttributeString( AtomCategorySchemeAttributeName, UnitTestsUtil.SchemeNamespace.NamespaceName); this.writer.WriteEndElement(); }
protected override void PreWriteProperties(DSPResource entry) { // For MLEs, the <m:properties> element is outside of the content element and we can omit the content element. if (!entry.ResourceType.IsMediaLinkEntry) { // <content type="type"> this.writer.WriteStartElement( AtomContentElementName, UnitTestsUtil.AtomNamespace.NamespaceName); this.writer.WriteAttributeString( AtomTypeAttributeName, UnitTestsUtil.MimeApplicationXml); } // <m:properties> this.writer.WriteStartElement( PropertiesElementName, UnitTestsUtil.MetadataNamespace.NamespaceName); }
private static void ExecuteUpdate(DSPResource resource, int id, TestWebRequest baseRequest, string httpMethod, string preferHeader, bool useBatch, DSPResourceSerializerFormat payloadFormat) { string payload = DSPResourceSerializer.WriteEntity(resource, payloadFormat); bool isPost = httpMethod == "POST"; bool expectedReturnContent = preferHeader == "return=representation" || isPost && preferHeader == null; string uriSuffix = isPost ? String.Empty : String.Format("({0})", id); TestWebRequest request = useBatch ? new InMemoryWebRequest() : baseRequest; request.RequestUriString = String.Format("/{0}s{1}", resource.ResourceType.Name, uriSuffix); request.HttpMethod = httpMethod; request.RequestVersion = "4.0;"; request.RequestMaxVersion = "4.0;"; request.RequestHeaders["Prefer"] = preferHeader; request.Accept = payloadFormat == DSPResourceSerializerFormat.Atom ? "application/atom+xml,application/xml" : UnitTestsUtil.JsonLightMimeType; request.RequestContentType = "application/atom+xml"; request.SetRequestStreamAsText(payload); if (useBatch) { var batchRequest = new BatchWebRequest(); var changeset = new BatchWebRequest.Changeset(); changeset.Parts.Add((InMemoryWebRequest)request); batchRequest.Changesets.Add(changeset); batchRequest.SendRequest(baseRequest); Assert.IsTrue(UnitTestsUtil.IsSuccessStatusCode(baseRequest.ResponseStatusCode), "Unexpected error occurred on batch."); } else { request.SendRequest(); } Assert.IsTrue(UnitTestsUtil.IsSuccessStatusCode(request.ResponseStatusCode), "Unexpected error occurred when sending the request."); if (expectedReturnContent) { // If the request is expected to return content, verify there were no instream errors Exception e = request.ParseResponseInStreamError(); string errorMessage = e != null ? e.Message : string.Empty; Assert.IsNull(e, "Expected no exception, but got the following error", errorMessage); } }
/// <summary>Creates a server resource from the specified client resource</summary> /// <param name="clientResource">The client resource instance.</param> /// <param name="createCollection">Optional func to create a new collection instance on the server. /// The first parameter is the collection resource type, the second is enumeration of server items to be added to the collection.</param> /// <param name="clientInstanceToResourceType">Func to resolve client resource to a server resource type.</param> /// <returns>The server resource instance.</returns> public static DSPResource CreateServerResourceFromClientResource( object clientResource, Func<providers.CollectionResourceType, IEnumerable<object>, object> createCollection, Func<object, providers.ResourceType> clientInstanceToResourceType) { providers.ResourceType resourceType = clientInstanceToResourceType(clientResource); DSPResource resource = new DSPResource(resourceType); IEnumerable<PropertyInfo> properties = clientResource.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); foreach (var property in properties) { var sameProperties = properties.Where(p => p.Name == property.Name).ToList(); sameProperties.Sort((p1, p2) => p1.DeclaringType.IsAssignableFrom(p2.DeclaringType) ? 1 : -1); if (sameProperties[0] == property) { object value = property.GetValue(clientResource, null); providers.ResourceProperty resourceProperty = resourceType == null ? null : resourceType.Properties.SingleOrDefault(p => p.Name == property.Name); resource.SetRawValue(property.Name, CreateServerValueFromClientValue(value, resourceProperty == null ? null : resourceProperty.ResourceType, createCollection, clientInstanceToResourceType)); } } return resource; }