private ExpectedClientRequest CreateSaveStreamRequest(StreamDescriptorData streamDescriptorData, Uri requestUri)
        {
            HttpVerb verb;

            if (streamDescriptorData.State == EntityStates.Added)
            {
                verb = HttpVerb.Post;
            }
            else
            {
                ExceptionUtilities.Assert(streamDescriptorData.State == EntityStates.Modified, "Stream descriptor state should only be added or modified. State was: '{0}'", streamDescriptorData.State);
                verb = HttpVerb.Put;
            }

            var request = new ExpectedClientRequest()
            {
                Verb = verb, Uri = requestUri
            };

            foreach (var header in streamDescriptorData.SaveStream.Headers)
            {
                request.Headers.Add(header);
            }

            request.Body = new PrimitiveValue(null, streamDescriptorData.SaveStream.StreamLogger.GetAllBytesRead());
            return(request);
        }
Exemplo n.º 2
0
            private void VerifyStreamClosed(StreamDescriptorData streamDescriptor)
            {
                var saveStream = streamDescriptor.SaveStream;

                if (saveStream != null)
                {
                    this.parent.Assert.IsTrue(saveStream.StreamLogger.IsEndOfStream, string.Format(CultureInfo.InvariantCulture, "Stream was not read to the end: {0}", streamDescriptor));
                    this.parent.Assert.AreEqual(
                        saveStream.CloseStream,
                        saveStream.StreamLogger.IsClosed,
                        string.Format(CultureInfo.InvariantCulture, "Save stream should/should not have been closed: {0}", streamDescriptor));
                    streamDescriptor.SaveStream = null;
                }
            }
Exemplo n.º 3
0
        private void VerifyDescriptor(DescriptorData expected, Descriptor actual, int responseOrder)
        {
            EntityDescriptorData entityDescriptorData = expected as EntityDescriptorData;
            LinkDescriptorData   linkDescriptorData   = expected as LinkDescriptorData;
            StreamDescriptorData streamDescriptorData = expected as StreamDescriptorData;

            if (entityDescriptorData != null)
            {
                EntityDescriptor entityDescriptor = actual as EntityDescriptor;
                this.Assert.IsNotNull(entityDescriptor, GetVerificationFailureMessage(responseOrder, "Unexpected descriptor type:\r\nExpected: {0}\r\nActual:   {1}\r\nExpected descriptor data: {2}.", typeof(EntityDescriptor).Name, actual.GetType().Name, entityDescriptorData));

                this.Assert.AreSame(
                    entityDescriptorData.Entity,
                    entityDescriptor.Entity,
                    GetVerificationFailureMessage(responseOrder, "Entity verification failed for the entity descriptor data: {0}.", expected));
            }
            else if (linkDescriptorData != null)
            {
                LinkDescriptor linkDescriptor = actual as LinkDescriptor;
                this.Assert.IsNotNull(linkDescriptor, GetVerificationFailureMessage(responseOrder, "Unexpected descriptor type:\r\nExpected: {0}\r\nActual:   {1}\r\nExpected descriptor data: {2}.", typeof(LinkDescriptor).Name, actual.GetType().Name, linkDescriptorData));

                bool notMatch = linkDescriptorData.SourceDescriptor.Entity != linkDescriptor.Source ||
                                (linkDescriptorData.TargetDescriptor == null && linkDescriptor.Target != null) ||
                                (linkDescriptorData.TargetDescriptor != null && linkDescriptorData.TargetDescriptor.Entity != linkDescriptor.Target) ||
                                linkDescriptorData.SourcePropertyName != linkDescriptor.SourceProperty;

                this.Assert.IsFalse(notMatch, GetVerificationFailureMessage(responseOrder, "Link verification failed.\r\nExpected: {0}\r\nActual:   {1}", linkDescriptorData, linkDescriptor.ToTraceString()));
            }
            else
            {
#if WINDOWS_PHONE
                throw new TaupoNotSupportedException("StreamDescriptors are not supported on Windows Phone");
#else
                ExceptionUtilities.CheckObjectNotNull(streamDescriptorData, "Expected was not an entity, link, or stream descriptor: {0}", expected);

                StreamDescriptor streamDescriptor = actual as StreamDescriptor;

                this.Assert.IsNotNull(streamDescriptor, GetVerificationFailureMessage(responseOrder, "Unexpected descriptor type:\r\nExpected: {0}\r\nActual:   {1}\r\nExpected descriptor data: {2}.", typeof(StreamDescriptor).Name, actual.GetType().Name, streamDescriptorData));

                this.Assert.AreEqual(streamDescriptorData.State.ToProductEnum(), streamDescriptor.State, GetVerificationFailureMessage(responseOrder, "Stream descriptor state verification failed."));
                this.Assert.AreEqual(streamDescriptorData.Name, streamDescriptor.StreamLink.Name, GetVerificationFailureMessage(responseOrder, "Stream descriptor name verification failed."));
                this.Assert.AreEqual(streamDescriptorData.ETag, streamDescriptor.StreamLink.ETag, GetVerificationFailureMessage(responseOrder, "Stream descriptor etag verification failed."));
                this.Assert.AreEqual(streamDescriptorData.ContentType, streamDescriptor.StreamLink.ContentType, GetVerificationFailureMessage(responseOrder, "Stream descriptor content type verification failed."));
                this.Assert.AreEqual(streamDescriptorData.EditLink, streamDescriptor.StreamLink.EditLink, GetVerificationFailureMessage(responseOrder, "Stream descriptor edit link verification failed."));
                this.Assert.AreEqual(streamDescriptorData.SelfLink, streamDescriptor.StreamLink.SelfLink, GetVerificationFailureMessage(responseOrder, "Stream descriptor self link verification failed."));
#endif
            }
        }
        private ExpectedClientRequest CreateStreamUpdateRequest(StreamDescriptorData streamDescriptorData, SaveChangesOptions options)
        {
            var request = this.CreateSaveStreamRequest(streamDescriptorData, streamDescriptorData.EditLink);

            request.Headers[HttpHeaders.IfMatch]            = streamDescriptorData.ETag;
            request.Headers[HttpHeaders.Prefer]             = null;
            request.Headers[HttpHeaders.DataServiceVersion] = ToClientHeaderFormat(DataServiceProtocolVersion.V4);
            this.SetDefaultAcceptHeader(request, options);
            SetContentTypeHeaderForStream(request, streamDescriptorData);

            string hintString = @"Stream update\r\n{{\r\n  Descriptor = {0}\r\n\r\n}}";

            request.DebugHintString = string.Format(CultureInfo.InvariantCulture, hintString, streamDescriptorData);

            return(request);
        }
        private ExpectedClientRequest CreateStreamInsertRequest(DataServiceContextData contextData, StreamDescriptorData streamDescriptorData, SaveChangesOptions options)
        {
            ExceptionUtilities.Assert(streamDescriptorData.Name == null, "Can only be used for media-resources");

            var insertUri = GetEntityInsertUri(contextData, streamDescriptorData.EntityDescriptor);

            var request = this.CreateSaveStreamRequest(streamDescriptorData, insertUri);

            string preference = contextData.AddAndUpdateResponsePreference.ToHeaderValue();
            var    dsv        = GetDataServiceVersion(request.Verb, preference);

            request.Headers[HttpHeaders.DataServiceVersion] = ToClientHeaderFormat(dsv);
            request.Headers[HttpHeaders.IfMatch]            = null;
            request.Headers[HttpHeaders.Prefer]             = preference;

            this.SetDefaultAcceptHeader(request, options);
            SetContentTypeHeaderForStream(request, streamDescriptorData);

            string hintString = @"Stream insert\r\n{{\r\n  Descriptor = {0}\r\n\r\n}}";

            request.DebugHintString = string.Format(CultureInfo.InvariantCulture, hintString, streamDescriptorData);

            return(request);
        }
        private static void SetContentTypeHeaderForStream(ExpectedClientRequest request, StreamDescriptorData streamDescriptorData)
        {
            request.Headers[HttpHeaders.ContentType] = streamDescriptorData.ContentType;
            if (streamDescriptorData.ContentType == null)
            {
                request.Headers[HttpHeaders.ContentType] = MimeTypes.Any;
            }

            foreach (var header in streamDescriptorData.SaveStream.Headers)
            {
                request.Headers[header.Key] = header.Value;
            }

            request.Headers[HttpHeaders.Accept] = DefaultAccept;
        }
Exemplo n.º 7
0
        /// <summary>
        /// Tracks the SaveChanges method.
        /// </summary>
        /// <param name="data">The data service context data on which to apply state transition.</param>
        /// <param name="options">The options.</param>
        /// <param name="response">The response.</param>
        /// <param name="cachedOperationsFromResponse">The individual operation respones, pre-enumerated and cached.</param>
        /// <param name="tracker">The entity data change tracker to use</param>
        public static void TrackSaveChanges(this DataServiceContextData data, SaveChangesOptions options, DSClient.DataServiceResponse response, IEnumerable <DSClient.OperationResponse> cachedOperationsFromResponse, IEntityDescriptorDataChangeTracker tracker)
        {
            ExceptionUtilities.CheckArgumentNotNull(data, "data");
            ExceptionUtilities.CheckArgumentNotNull(response, "response");
            ExceptionUtilities.CheckArgumentNotNull(cachedOperationsFromResponse, "cachedOperationsFromResponse");
            ExceptionUtilities.CheckArgumentNotNull(tracker, "tracker");

            // Check options and response consistency
            if ((options & SaveChangesOptions.ContinueOnError) == 0)
            {
                ExceptionUtilities.Assert(response.Count(r => r.Error != null) == 0, "Check save changes options and response consistency: no errors in the response when ContinueOnError is off.");
            }

            // because some links will not have separate requests, we need to keep track of all link changes
            var allPendingLinkChanges = data.GetOrderedChanges().OfType <LinkDescriptorData>().ToList();

            // go through the pending changes and update the states based on whether the request succeeded
            foreach (DSClient.ChangeOperationResponse changeResponse in cachedOperationsFromResponse)
            {
                DescriptorData       descriptorData;
                LinkDescriptorData   linkDescriptorData   = null;
                StreamDescriptorData streamDescriptorData = null;
                var entityDescriptor = changeResponse.Descriptor as DSClient.EntityDescriptor;
                if (entityDescriptor != null)
                {
                    descriptorData = data.GetEntityDescriptorData(entityDescriptor.Entity);
                }
                else
                {
                    var linkDescriptor = changeResponse.Descriptor as DSClient.LinkDescriptor;
                    if (linkDescriptor != null)
                    {
                        linkDescriptorData = data.GetLinkDescriptorData(linkDescriptor.Source, linkDescriptor.SourceProperty, linkDescriptor.Target);
                        descriptorData     = linkDescriptorData;
                        allPendingLinkChanges.Remove(linkDescriptorData);
                    }
                    else
                    {
                        // for stream descriptors, we need to find the parent descriptor, then get the stream descriptor data from it
                        var streamDescriptor = (DSClient.StreamDescriptor)changeResponse.Descriptor;

                        entityDescriptor     = streamDescriptor.EntityDescriptor;
                        streamDescriptorData = data.GetStreamDescriptorData(entityDescriptor.Entity, streamDescriptor.StreamLink.Name);
                        descriptorData       = streamDescriptorData;
                    }
                }

                // don't update states for responses that indicate failure
                if (changeResponse.Error != null)
                {
                    continue;
                }

                // because the request succeeded, make the corresponding updates to the states
                if (descriptorData.State == EntityStates.Deleted ||
                    (linkDescriptorData != null &&
                     linkDescriptorData.State == EntityStates.Modified &&
                     linkDescriptorData.SourceDescriptor.State == EntityStates.Deleted))
                {
                    data.RemoveDescriptorData(descriptorData);
                }
                else
                {
                    // for non-deleted descriptors, we need to update states based on the headers
                    var entityDescriptorData = descriptorData as EntityDescriptorData;
                    if (entityDescriptorData != null)
                    {
                        if (entityDescriptorData.IsMediaLinkEntry && entityDescriptorData.DefaultStreamState == EntityStates.Modified)
                        {
                            entityDescriptorData.DefaultStreamDescriptor.UpdateFromHeaders(changeResponse.Headers);
                            entityDescriptorData.DefaultStreamState = EntityStates.Unchanged;
                        }
                        else
                        {
                            if (entityDescriptorData.IsMediaLinkEntry && entityDescriptorData.DefaultStreamState == EntityStates.Added)
                            {
                                entityDescriptorData.DefaultStreamState = EntityStates.Unchanged;
                            }

                            // because there might have been a reading-entity event for this entity, we need to apply the headers through the tracker
                            tracker.TrackUpdateFromHeaders(entityDescriptorData, changeResponse.Headers);

                            // ensure that all updates are applied before moving to the next response
                            tracker.ApplyPendingUpdates(entityDescriptorData);

                            entityDescriptorData.ParentForInsert         = null;
                            entityDescriptorData.ParentPropertyForInsert = null;
                            entityDescriptorData.InsertLink = null;
                        }
                    }
                    else if (streamDescriptorData != null)
                    {
                        streamDescriptorData.UpdateFromHeaders(changeResponse.Headers);
                    }

                    descriptorData.State = EntityStates.Unchanged;
                }
            }

            // go through each link change that did not have an assocatiated response and update its state
            foreach (var linkDescriptorData in allPendingLinkChanges.OfType <LinkDescriptorData>())
            {
                if (linkDescriptorData.State == EntityStates.Added || linkDescriptorData.State == EntityStates.Modified)
                {
                    linkDescriptorData.State = EntityStates.Unchanged;
                }
            }
        }