Esempio n. 1
0
        /// <summary>
        /// Verifies the named streams.
        /// </summary>
        /// <param name="dataContext">The data context.</param>
        /// <param name="queryEntityValue">The query entity value.</param>
        /// <param name="streamProperty">The stream property.</param>
        /// <param name="ed">The entity descriptor</param>
        /// <param name="continuation">The stream descriptor continuation.</param>
        private void VerifyNamedStreams(DataServiceContext dataContext, QueryStructuralValue queryEntityValue, QueryProperty streamProperty, EntityDescriptor ed, IAsyncContinuation continuation)
        {
            var expectedStreamValue = queryEntityValue.GetStreamValue(streamProperty.Name);
            var streamDescriptor    = ed.StreamDescriptors.SingleOrDefault(s => s.StreamLink.Name == streamProperty.Name);

            this.Assert.IsNotNull(streamDescriptor, "Entity missing stream descriptor for stream '{0}'", streamProperty.Name);
            this.VerifyStreamLink(expectedStreamValue, streamDescriptor.StreamLink);

            var expectedReadStreamUri = GetExpectedReadStreamUri(expectedStreamValue);

            Uri readStreamUri = dataContext.GetReadStreamUri(ed.Entity, streamProperty.Name);

            this.Assert.AreEqual(expectedReadStreamUri, readStreamUri, "Read stream uri did not match for stream '{0}'", streamProperty.Name);

            dataContext.GetReadStream(
                continuation,
                this.isAsynchronous,
                ed.Entity,
                streamProperty.Name,
                new DataServiceRequestArgs()
            {
            },
                response =>
            {
                UpdateStreamValueFromHeaders(expectedStreamValue, response);
                this.VerifyStreamLink(expectedStreamValue, streamDescriptor.StreamLink);
                // skip this verification when using payload driven verification since we don't have the expected content for streams
                if (!this.DataProviderSettings.UsePayloadDrivenVerification)
                {
                    this.Assert.IsTrue(this.VerifyStreams(expectedStreamValue, response), "Failed to compare value of stream '{0}'", streamProperty.Name);
                }

                continuation.Continue();
            });
        }
Esempio n. 2
0
        private string CalculateExpectedETagForEntityOrStream(ODataUri uri, QueryStructuralValue entity)
        {
            if (uri.IsMediaResource())
            {
                return(entity.GetDefaultStreamValue().GetExpectedETag());
            }

            if (uri.IsNamedStream())
            {
                var streamSegment = uri.Segments.OfType <NamedStreamSegment>().Last();
                return(entity.GetStreamValue(streamSegment.Name).GetExpectedETag());
            }

            return(this.LiteralConverter.ConstructWeakETag(entity));
        }
Esempio n. 3
0
        private void VerifyStoreData(ODataRequest request, ODataResponse response, QueryStructuralValue storeValue)
        {
            string contentType;

            ExceptionUtilities.Assert(request.Headers.TryGetValue(HttpHeaders.ContentType, out contentType), "Could not get Content-Type header from request");

            if (request.Uri.IsNamedStream())
            {
                string streamName  = request.Uri.Segments.OfType <NamedStreamSegment>().Last().Name;
                var    streamValue = storeValue.GetStreamValue(streamName);
                this.VerifyStream(streamValue, contentType, request, response);
                return;
            }

            bool isInsert        = request.GetEffectiveVerb() == HttpVerb.Post;
            bool isMediaResource = request.Uri.IsMediaResource();

            if (isInsert)
            {
                EntitySet expectedEntitySet;
                if (request.Uri.TryGetExpectedEntitySet(out expectedEntitySet))
                {
                    isMediaResource = expectedEntitySet.EntityType.HasStream();
                }
            }

            if (isMediaResource)
            {
                var streamValue = storeValue.GetDefaultStreamValue();
                this.VerifyStream(streamValue, contentType, request, response);
            }
            else
            {
                if (isInsert)
                {
                    this.VerifyTypeNameForInsert(request, response, storeValue);
                }

                var formatStrategy    = this.FormatSelector.GetStrategy(contentType, request.Uri);
                var primitiveComparer = formatStrategy.GetPrimitiveComparer();

                // TODO: verify relationships
                // TODO: verify PUT vs PATCH semantics
                this.VerifyPropertyValues(request, primitiveComparer, storeValue);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Sets the values of a stream property
        /// </summary>
        /// <param name="instance">The entity which contains the stream property</param>
        /// <param name="name">The name of the stream property or null to indicate the default stream</param>
        /// <param name="contentType">The stream's content type</param>
        /// <param name="etag">The stream's etag</param>
        /// <param name="editLink">The stream's edit-link</param>
        /// <param name="selfLink">The stream's self-link</param>
        /// <param name="content">The stream's content</param>
        internal static void SetStreamValue(this QueryStructuralValue instance, string name, string contentType, string etag, string editLink, string selfLink, byte[] content)
        {
            ExceptionUtilities.CheckArgumentNotNull(instance, "instance");

            if (name == null)
            {
                name = AstoriaQueryStreamType.DefaultStreamPropertyName;
            }

            var value = instance.GetStreamValue(name);

            // if its null, it may not have been initialized at all, so reassign it to be safe
            if (value.IsNull)
            {
                instance.SetStreamValue(name, value);
            }

            value.Value       = content;
            value.ContentType = contentType;
            value.ETag        = etag;

            value.EditLink = CreateRelativeOrAbsoluteUriOrReturnNull(editLink);
            value.SelfLink = CreateRelativeOrAbsoluteUriOrReturnNull(selfLink);
        }
Esempio n. 5
0
        /// <summary>
        /// Compares properties of a structural object with expected value. Overridden here to handle named streams.
        /// </summary>
        /// <param name="structuralValue">The structural object containing the property to compare</param>
        /// <param name="expectedName">The name of the property to compare</param>
        /// <param name="expectedPropertyType">The expected type of the property</param>
        /// <param name="actualValue">The actual value of the property</param>
        /// <param name="path">The path to the compared object (for debugging purposes)</param>
        /// <param name="shouldThrow">Should exception be thrown if error is encountered</param>
        /// <returns>The comparison result</returns>
        protected override ComparisonResult CompareProperty(QueryStructuralValue structuralValue, string expectedName, QueryType expectedPropertyType, object actualValue, string path, bool shouldThrow)
        {
            if (this.CodeGenerator.GetType() == typeof(RemoteClientCodeLayerGenerator))
            {
                if (structuralValue.GetValue(expectedName).IsNull&& expectedPropertyType is QueryComplexType)
                {
                    return(ComparisonResult.Success);
                }
            }

            if (expectedPropertyType is AstoriaQueryStreamType)
            {
                DataServiceStreamLink   actualStreamLink    = (DataServiceStreamLink)actualValue;
                AstoriaQueryStreamValue expectedStreamValue = (AstoriaQueryStreamValue)structuralValue.GetStreamValue(expectedName);

                if (actualStreamLink == null)
                {
                    if (!expectedStreamValue.IsNull)
                    {
                        this.ThrowOrLogError(shouldThrow, "Expected DataServiceStreamLink property to be null. Actual: {0}", actualStreamLink);
                        return(ComparisonResult.Failure);
                    }
                    else
                    {
                        return(ComparisonResult.Success);
                    }
                }

                try
                {
                    this.VerifyStreamLink(expectedStreamValue, actualStreamLink);
                    return(ComparisonResult.Success);
                }
                catch (TestFailedException e)
                {
                    this.ThrowOrLogError(shouldThrow, e.ToString());
                    return(ComparisonResult.Failure);
                }
            }
            else
            {
                return(base.CompareProperty(structuralValue, expectedName, expectedPropertyType, actualValue, path, shouldThrow));
            }
        }
Esempio n. 6
0
        private string CalculateExpectedETagForEntityOrStream(ODataUri uri, QueryStructuralValue entity)
        {
            if (uri.IsMediaResource())
            {
                return entity.GetDefaultStreamValue().GetExpectedETag();
            }

            if (uri.IsNamedStream())
            {
                var streamSegment = uri.Segments.OfType<NamedStreamSegment>().Last();
                return entity.GetStreamValue(streamSegment.Name).GetExpectedETag();
            }

            return this.LiteralConverter.ConstructWeakETag(entity);
        }
Esempio n. 7
0
        private void ProcessEntityAndGenerateStreams(QueryStructuralValue queryStructuralValue, IAsyncContinuation continuation, HttpWebResponse response)
        {
            ExceptionUtilities.Assert(response.StatusCode == HttpStatusCode.OK, "Error generating stream data, response code incorrect:" + response.StatusCode.ToString());
            var responseValue = new StreamReader(response.GetResponseStream()).ReadToEnd();

            try
            {
                var existingEntityInXML = XElement.Parse(responseValue);
                var feedInstance        = this.XmlToPayloadConverter.ConvertToPayloadElement(existingEntityInXML) as EntitySetInstance;
                ExceptionUtilities.CheckObjectNotNull(feedInstance, "Error generating stream data, cannot deserialize response:" + existingEntityInXML);

                var type = queryStructuralValue.Type as QueryEntityType;
                ExceptionUtilities.CheckObjectNotNull(type, "Type was not an entity type. Type was {0}", type.StringRepresentation);

                Func <AstoriaQueryStreamValue, bool> valueFilter    = v => v.IsNull || v.Value.Length == 0;
                Func <QueryProperty, bool>           propertyFilter = p => p.IsStream() && valueFilter(queryStructuralValue.GetStreamValue(p.Name));
                var streamPropertiesToUpdate = type.Properties.Where(propertyFilter).ToList();

                if (feedInstance.Count != 0)
                {
                    var entityInstance = feedInstance.SingleOrDefault();
                    ExceptionUtilities.CheckObjectNotNull(entityInstance, "Payload did not contain a single entity instance");

                    var baseAddressAnnotation = feedInstance.Annotations.OfType <XmlBaseAnnotation>().SingleOrDefault();

                    foreach (var streamProperty in streamPropertiesToUpdate)
                    {
                        var streamPropertyType = streamProperty.PropertyType as AstoriaQueryStreamType;
                        ExceptionUtilities.CheckObjectNotNull(streamPropertyType, "PropertyType is not an AstoriaQueryStreamType!", streamProperty.PropertyType);

                        var streamData = this.GenerateStreamData(entityInstance, baseAddressAnnotation, streamProperty);
                        this.streamsToUpdate.Add(streamData);
                    }
                }

                continuation.Continue();
            }
            catch (XmlException)
            {
                this.Logger.WriteLine(LogLevel.Error, "Error in Xml payload:" + responseValue);

                throw;
            }
        }
Esempio n. 8
0
        private void ProcessEntityAndGenerateStreams(QueryStructuralValue queryStructuralValue, IAsyncContinuation continuation, HttpWebResponse response)
        {
            ExceptionUtilities.Assert(response.StatusCode == HttpStatusCode.OK, "Error generating stream data, response code incorrect:" + response.StatusCode.ToString());
            var responseValue = new StreamReader(response.GetResponseStream()).ReadToEnd();

            try
            {
                var existingEntityInXML = XElement.Parse(responseValue);
                var feedInstance = this.XmlToPayloadConverter.ConvertToPayloadElement(existingEntityInXML) as EntitySetInstance;
                ExceptionUtilities.CheckObjectNotNull(feedInstance, "Error generating stream data, cannot deserialize response:" + existingEntityInXML);

                var type = queryStructuralValue.Type as QueryEntityType;
                ExceptionUtilities.CheckObjectNotNull(type, "Type was not an entity type. Type was {0}", type.StringRepresentation);

                Func<AstoriaQueryStreamValue, bool> valueFilter = v => v.IsNull || v.Value.Length == 0;
                Func<QueryProperty, bool> propertyFilter = p => p.IsStream() && valueFilter(queryStructuralValue.GetStreamValue(p.Name));
                var streamPropertiesToUpdate = type.Properties.Where(propertyFilter).ToList();

                if (feedInstance.Count != 0)
                {
                    var entityInstance = feedInstance.SingleOrDefault();
                    ExceptionUtilities.CheckObjectNotNull(entityInstance, "Payload did not contain a single entity instance");

                    var baseAddressAnnotation = feedInstance.Annotations.OfType<XmlBaseAnnotation>().SingleOrDefault();

                    foreach (var streamProperty in streamPropertiesToUpdate)
                    {
                        var streamPropertyType = streamProperty.PropertyType as AstoriaQueryStreamType;
                        ExceptionUtilities.CheckObjectNotNull(streamPropertyType, "PropertyType is not an AstoriaQueryStreamType!", streamProperty.PropertyType);

                        var streamData = this.GenerateStreamData(entityInstance, baseAddressAnnotation, streamProperty);
                        this.streamsToUpdate.Add(streamData);
                    }
                }

                continuation.Continue();
            }
            catch (XmlException)
            {
                this.Logger.WriteLine(LogLevel.Error, "Error in Xml payload:" + responseValue);

                throw;
            }
        }
        private QueryStructuralValue CloneStructuralValue(Dictionary<QueryStructuralValue, QueryStructuralValue> identityMap, QueryStructuralValue qsv)
        {
            if (qsv.IsNull)
            {
                return qsv;
            }

            QueryStructuralValue clonedValue;

            if (identityMap.TryGetValue(qsv, out clonedValue))
            {
                return clonedValue;
            }

            clonedValue = qsv.Type.CreateNewInstance();
            identityMap.Add(qsv, clonedValue);
      
            foreach (var m in qsv.Type.Properties)
            {
                // copy scalar properties
                if (m.PropertyType is QueryScalarType)
                {
                    clonedValue.SetValue(m.Name, qsv.GetScalarValue(m.Name));
                    continue;
                }

                // copy stream properties
                if (m.PropertyType is AstoriaQueryStreamType)
                {
                    if (m.Name.Contains("DefaultStream"))
                    {
                        clonedValue.SetDefaultStreamValue(qsv.GetDefaultStreamValue());
                    }
                    else
                    {
                        clonedValue.SetStreamValue(m.Name, qsv.GetStreamValue(m.Name));
                    }

                    continue;
                }

                var qst = m.PropertyType as QueryStructuralType;
                if (m.PropertyType is QueryStructuralType)
                {
                    if (!qst.IsValueType)
                    {
                        // skip reference types, clone everything else
                        continue;
                    }

                    clonedValue.SetValue(m.Name, this.CloneStructuralValue(identityMap, qsv.GetStructuralValue(m.Name)));
                }

                var qct = m.PropertyType as QueryCollectionType;
                if (qct != null)
                {
                    var elementStructuralType = qct.ElementType as QueryStructuralType;
                    if (elementStructuralType != null)
                    {
                        if (!elementStructuralType.IsValueType)
                        {
                            // skip collections of reference types, clone everything else
                            continue;
                        }
                    }

                    clonedValue.SetValue(m.Name, this.CloneCollectionValue(identityMap, qsv.GetCollectionValue(m.Name)));
                }
            }

            return clonedValue;
        }
Esempio n. 10
0
        /// <summary>
        /// Returns the default stream property values for the given entity instance
        /// </summary>
        /// <param name="instance">The instance to get stream property values from</param>
        /// <returns>The stream values of the given instance</returns>
        public static AstoriaQueryStreamValue GetDefaultStreamValue(this QueryStructuralValue instance)
        {
            ExceptionUtilities.CheckArgumentNotNull(instance, "instance");

            return(instance.GetStreamValue(AstoriaQueryStreamType.DefaultStreamPropertyName));
        }
        private void VerifyStoreData(ODataRequest request, ODataResponse response, QueryStructuralValue storeValue)
        {
            string contentType;
            ExceptionUtilities.Assert(request.Headers.TryGetValue(HttpHeaders.ContentType, out contentType), "Could not get Content-Type header from request");

            if (request.Uri.IsNamedStream())
            {
                string streamName = request.Uri.Segments.OfType<NamedStreamSegment>().Last().Name;
                var streamValue = storeValue.GetStreamValue(streamName);
                this.VerifyStream(streamValue, contentType, request, response);
                return;
            }

            bool isInsert = request.GetEffectiveVerb() == HttpVerb.Post;
            bool isMediaResource = request.Uri.IsMediaResource();
            if (isInsert)
            {
                EntitySet expectedEntitySet;
                if (request.Uri.TryGetExpectedEntitySet(out expectedEntitySet))
                {
                    isMediaResource = expectedEntitySet.EntityType.HasStream();
                }
            }

            if (isMediaResource)
            {
                var streamValue = storeValue.GetDefaultStreamValue();
                this.VerifyStream(streamValue, contentType, request, response);
            }
            else
            {
                if (isInsert)
                {
                    this.VerifyTypeNameForInsert(request, response, storeValue);
                }

                var formatStrategy = this.FormatSelector.GetStrategy(contentType, request.Uri);
                var primitiveComparer = formatStrategy.GetPrimitiveComparer();

                // TODO: verify relationships
                // TODO: verify PUT vs PATCH semantics
                this.VerifyPropertyValues(request, primitiveComparer, storeValue);
            }
        }