示例#1
0
        /// <summary>
        /// Callback for the Download HttpWebRequest.beginGetRequestStream. Deserializes the response feed to
        /// retrieve the list of IOfflineEntity objects and constructs an ChangeSet for that.
        /// </summary>
        private async Task ReadDownloadResponse(HttpWebResponse response, AsyncArgsWrapper wrapper)
        {
            try
            {
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    Stream responseStream = response.GetResponseStream();

                    // Create the SyncReader
                    this.syncReader = (SerializationFormat == SerializationFormat.ODataAtom)
                        ? new ODataAtomReader(responseStream, this.knownTypes)
                        : (SyncReader) new ODataJsonReader(responseStream, this.knownTypes);

                    await Task.Factory.StartNew(() =>
                    {
                        // Read the response
                        while (syncReader.Next())
                        {
                            switch (syncReader.ItemType)
                            {
                            case ReaderItemType.Entry:
                                wrapper.DownloadResponse.AddItem(syncReader.GetItem());
                                break;

                            case ReaderItemType.SyncBlob:
                                wrapper.DownloadResponse.ServerBlob = syncReader.GetServerBlob();
                                break;

                            case ReaderItemType.HasMoreChanges:
                                wrapper.DownloadResponse.IsLastBatch = !syncReader.GetHasMoreChangesValue();
                                break;
                            }
                        }
                    });
                }
                else
                {
                    wrapper.Error = new CacheControllerException(
                        string.Format("Remote service returned error status. Status: {0}, Description: {1}",
                                      response.StatusCode,
                                      response.StatusDescription));
                }
            }
            catch (Exception e)
            {
                if (ExceptionUtility.IsFatal(e))
                {
                    throw;
                }
                wrapper.Error = e;
            }
        }
示例#2
0
        static void Main()
        {
            Stopwatch   stopWatch   = Stopwatch.StartNew();
            AsyncReader asyncReader = new AsyncReader(filePath);

            asyncReader.MainAsync().GetAwaiter().GetResult();
            stopWatch.Stop();
            string resultAsync = ($"{stopWatch.Elapsed}");

            stopWatch.Start();
            SyncReader syncReader = new SyncReader(filePath);

            syncReader.MainSync();
            stopWatch.Stop();
            string resultSync = ($"{stopWatch.Elapsed}");

            Console.WriteLine($"\nAsync \t\t {resultAsync}\nSync \t\t {resultSync}");
        }
示例#3
0
        Response IDnsClient.Process(Request request)
        {
            if (object.ReferenceEquals(null, request))
            {
                throw new ArgumentNullException("request");
            }

            // create request datagram, prefixed with the two byte length field
            Datagram qdata = Datagram.GetPrefixed(request.Data);

            NetworkStream ns = base.GetStream();

            if (RequestSending != null)
            {
                RequestSending(this, new MessageEventArgs(request, ns, (IPEndPoint)Client.RemoteEndPoint));
            }

            // LogMessage
            LogRequest(qdata.Length);

            // send prefixed request message
            request.SetTimestamp();
            ns.Write(qdata, 0, qdata.Length);

            // read response
            SyncReader reader = new SyncReader(ns);

            for (reader.Start(); reader.Next();)
            {
                ;
            }

            Response response = Response.Create((Datagram)reader.Data, DateTime.Now);

            // LogMessage
            LogResponse(response);

            return(response);
        }
        /// <summary>
        /// Callback for the Download HttpWebRequest.beginGetRequestStream. Deserializes the response feed to
        /// retrieve the list of IOfflineEntity objects and constructs an ChangeSet for that.
        /// </summary>
        /// <param name="asyncResult">IAsyncResult object</param>
        void OnDownloadGetResponseCompleted(IAsyncResult asyncResult)
        {
            AsyncArgsWrapper wrapper = asyncResult.AsyncState as AsyncArgsWrapper;

            wrapper.DownloadResponse = new ChangeSet();

            HttpWebResponse response = null;

            try
            {
                try
                {
                    response = wrapper.WebRequest.EndGetResponse(asyncResult) as HttpWebResponse;
                    if (String.IsNullOrEmpty(behaviors.UserId))
                    {
                        behaviors.UserId = response.Headers["userid"];
                    }
                    if (string.IsNullOrWhiteSpace(behaviors.UserEmail))
                    {
                        behaviors.UserEmail = response.Headers["email"];
                    }
                    behaviors.ResourceVersion = response.Headers["resourceversion"];
                }
                catch (WebException we)
                {
                    wrapper.Error = we;
                    // If we get here then it means we completed the request. Return to the original caller
                    this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper);
                    return;
                }
                catch (SecurityException se)
                {
                    wrapper.Error = se;
                    // If we get here then it means we completed the request. Return to the original caller
                    this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper);
                    return;
                }

                if (response.StatusCode == HttpStatusCode.OK)
                {
                    behaviors.SaveUserSession();

                    int contentLength = (int)response.ContentLength;

                    if (response.Headers.AllKeys.Contains("unzippedcontentlength"))
                    {
                        string value = response.Headers["unzippedcontentlength"];
                        if (!int.TryParse(value, out contentLength))
                        {
                            throw new WebException("Invalid value of header unzippedcontentlength: " + value);
                        }
                    }

                    Stream responseStream = new ProgressStream(response.GetResponseStream()
                                                               , contentLength
                                                               , behaviors.ReadProgressCallback);

                    // CreateInstance the SyncReader
                    if (ApplicationContext.Current.Settings.BitMobileFormatterDisabled)
                    {
                        _syncReader = new ODataAtomReader(responseStream, _knownTypes);
                    }
                    else
                    {
                        _syncReader = new BMReader(responseStream, _knownTypes);
                    }

                    // Read the response
                    wrapper.DownloadResponse.Data = GetDownloadedValues(wrapper);

                    wrapper.WebResponse = response;
                    // Invoke user code on the correct synchronization context.
                    this.FirePostResponseHandler(wrapper);
                }
                else
                {
                    wrapper.Error = new CacheControllerException(
                        string.Format("Remote service returned error status. Status: {0}, Description: {1}",
                                      response.StatusCode,
                                      response.StatusDescription));
                }

                // If we get here then it means we completed the request. Return to the original caller
                this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper);
            }
            catch (Exception e)
            {
                if (ExceptionUtility.IsFatal(e))
                {
                    throw;
                }

                wrapper.Error = e;
                this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper);
            }
        }
        /// <summary>
        /// Callback for the Upload HttpWebRequest.BeginGetResponse call
        /// </summary>
        /// <param name="asyncResult">IAsyncResult object</param>
        void OnUploadGetResponseCompleted(IAsyncResult asyncResult)
        {
            AsyncArgsWrapper wrapper = asyncResult.AsyncState as AsyncArgsWrapper;

            wrapper.UploadResponse = new ChangeSetResponse();

            HttpWebResponse response = null;

            try
            {
                try
                {
                    response = wrapper.WebRequest.EndGetResponse(asyncResult) as HttpWebResponse;
                }
                catch (WebException we)
                {
                    wrapper.UploadResponse.Error = we;
                    // If we get here then it means we completed the request. Return to the original caller
                    this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper);
                    return;
                }
                catch (SecurityException se)
                {
                    wrapper.UploadResponse.Error = se;
                    // If we get here then it means we completed the request. Return to the original caller
                    this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper);
                    return;
                }

                if (response.StatusCode == HttpStatusCode.OK)
                {
                    Stream responseStream = response.GetResponseStream();

                    // CreateInstance the SyncReader
                    if (ApplicationContext.Current.Settings.BitMobileFormatterDisabled)
                    {
                        _syncReader = new ODataAtomReader(responseStream, _knownTypes);
                    }
                    else
                    {
                        _syncReader = new BMReader(responseStream, _knownTypes);
                    }

                    // Read the response
                    while (this._syncReader.Next())
                    {
                        switch (this._syncReader.ItemType)
                        {
                        case ReaderItemType.Entry:
                            IOfflineEntity entity      = this._syncReader.GetItem();
                            IOfflineEntity ackedEntity = entity;
                            string         tempId      = null;

                            // If conflict only one temp ID should be set
                            if (this._syncReader.HasTempId() && this._syncReader.HasConflictTempId())
                            {
                                throw new CacheControllerException(string.Format("Service returned a TempId '{0}' in both live and conflicting entities.",
                                                                                 this._syncReader.GetTempId()));
                            }

                            // Validate the live temp ID if any, before adding anything to the offline context
                            if (this._syncReader.HasTempId())
                            {
                                tempId = this._syncReader.GetTempId();
                                CheckEntityServiceMetadataAndTempIds(wrapper, entity, tempId);
                            }

                            //  If conflict
                            if (this._syncReader.HasConflict())
                            {
                                Conflict       conflict       = this._syncReader.GetConflict();
                                IOfflineEntity conflictEntity = (conflict is SyncConflict) ?
                                                                ((SyncConflict)conflict).LosingEntity : ((SyncError)conflict).ErrorEntity;

                                // Validate conflict temp ID if any
                                if (this._syncReader.HasConflictTempId())
                                {
                                    tempId = this._syncReader.GetConflictTempId();
                                    CheckEntityServiceMetadataAndTempIds(wrapper, conflictEntity, tempId);
                                }

                                // Add conflict
                                wrapper.UploadResponse.AddConflict(conflict);

                                //
                                // If there is a conflict and the tempId is set in the conflict entity then the client version lost the
                                // conflict and the live entity is the server version (ServerWins)
                                //
                                if (this._syncReader.HasConflictTempId() && entity.ServiceMetadata.IsTombstone)
                                {
                                    //
                                    // This is a ServerWins conflict, or conflict error. The winning version is a tombstone without temp Id
                                    // so there is no way to map the winning entity with a temp Id. The temp Id is in the conflict so we are
                                    // using the conflict entity, which has the PK, to build a tombstone entity used to update the offline context
                                    //
                                    // In theory, we should copy the service metadata but it is the same end result as the service fills in
                                    // all the properties in the conflict entity
                                    //

                                    // Add the conflict entity
                                    conflictEntity.ServiceMetadata.IsTombstone = true;
                                    ackedEntity = conflictEntity;
                                }
                            }

                            // Add ackedEntity to storage. If ackedEntity is still equal to entity then add non-conflict entity.
                            if (!String.IsNullOrEmpty(tempId))
                            {
                                wrapper.UploadResponse.AddUpdatedItem(ackedEntity);
                            }
                            break;

                        case ReaderItemType.SyncBlob:
                            wrapper.UploadResponse.ServerBlob = this._syncReader.GetServerBlob();
                            break;
                        }
                    }

                    wrapper.WebResponse = response;
                    // Invoke user code on the correct synchronization context.
                    this.FirePostResponseHandler(wrapper);
                }
                else
                {
                    wrapper.UploadResponse.Error = new CacheControllerException(
                        string.Format("Remote service returned error status. Status: {0}, Description: {1}",
                                      response.StatusCode,
                                      response.StatusDescription));
                }

                // If we get here then it means we completed the request. Return to the original caller
                this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper);
            }
            catch (Exception e)
            {
                if (ExceptionUtility.IsFatal(e))
                {
                    throw;
                }

                wrapper.Error = e;
                this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper);
            }
        }
示例#6
0
        Response IDnsClient.Process(Request request)
        {
            if (object.ReferenceEquals(null, request))
            throw new ArgumentNullException("request");

              // create request datagram, prefixed with the two byte length field
              Datagram qdata = Datagram.GetPrefixed(request.Data);

              NetworkStream ns = base.GetStream();
              if (RequestSending != null)
            RequestSending(this, new MessageEventArgs(request, ns, (IPEndPoint)Client.RemoteEndPoint));

              // LogMessage
              LogRequest(qdata.Length);

              // send prefixed request message
              request.SetTimestamp();
              ns.Write(qdata, 0, qdata.Length);

              // read response
              SyncReader reader = new SyncReader(ns);
              for (reader.Start(); reader.Next(); ) ;

              Response response = Response.Create((Datagram)reader.Data, DateTime.Now);

              // LogMessage
              LogResponse(response);

              return response;
        }
        /// <summary>
        /// Callback for the Download HttpWebRequest.beginGetRequestStream. Deserializes the response feed to
        /// retrieve the list of IOfflineEntity objects and constructs an ChangeSet for that.
        /// </summary>
        /// <param name="asyncResult">IAsyncResult object</param>
        void OnDownloadGetResponseCompleted(IAsyncResult asyncResult)
        {
            AsyncArgsWrapper wrapper = asyncResult.AsyncState as AsyncArgsWrapper;

            wrapper.DownloadResponse = new ChangeSet();

            HttpWebResponse response = null;

            try
            {
                try
                {
                    response = wrapper.WebRequest.EndGetResponse(asyncResult) as HttpWebResponse;
                }
                catch (WebException we)
                {
                    wrapper.Error = we;
                    // If we get here then it means we completed the request. Return to the original caller
                    this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper);
                    return;
                }
                catch (SecurityException se)
                {
                    wrapper.Error = se;
                    // If we get here then it means we completed the request. Return to the original caller
                    this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper);
                    return;
                }

                if (response.StatusCode == HttpStatusCode.OK)
                {
                    Stream responseStream = response.GetResponseStream();

                    // Create the SyncReader
                    this._syncReader = (base.SerializationFormat == ClientServices.SerializationFormat.ODataAtom)
                        ? (SyncReader) new ODataAtomReader(responseStream, this._knownTypes)
                        : (SyncReader) new ODataJsonReader(responseStream, this._knownTypes);

                    // Read the response
                    while (this._syncReader.Next())
                    {
                        switch (this._syncReader.ItemType)
                        {
                        case ReaderItemType.Entry:
                            wrapper.DownloadResponse.AddItem(this._syncReader.GetItem());
                            break;

                        case ReaderItemType.SyncBlob:
                            wrapper.DownloadResponse.ServerBlob = this._syncReader.GetServerBlob();
                            break;

                        case ReaderItemType.HasMoreChanges:
                            wrapper.DownloadResponse.IsLastBatch = !this._syncReader.GetHasMoreChangesValue();
                            break;
                        }
                    }

                    wrapper.WebResponse = response;
                    // Invoke user code on the correct synchronization context.
                    this.FirePostResponseHandler(wrapper);
                }
                else
                {
                    wrapper.Error = new CacheControllerException(
                        string.Format("Remote service returned error status. Status: {0}, Description: {1}",
                                      response.StatusCode,
                                      response.StatusDescription));
                }

                // If we get here then it means we completed the request. Return to the original caller
                this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper);
            }
            catch (Exception e)
            {
                if (ExceptionUtility.IsFatal(e))
                {
                    throw;
                }

                wrapper.Error = e;
                this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper);
            }
        }
示例#8
0
        private object ProcessUploadRequest(HttpWebRequest webRequest, CacheRequest request)
        {
            using (Stream memoryStream = new MemoryStream())
            {
                // Create a SyncWriter to write the contents
                this._syncWriter = new ODataAtomWriter(base.BaseUri);

                this._syncWriter.StartFeed(true, request.KnowledgeBlob ?? new byte[0]);

                foreach (IOfflineEntity entity in request.Changes)
                {
                    // Skip tombstones that dont have a ID element.
                    if (entity.ServiceMetadata.IsTombstone && string.IsNullOrEmpty(entity.ServiceMetadata.Id))
                    {
                        continue;
                    }

                    string tempId = null;

                    // Check to see if this is an insert. i.e ServiceMetadata.Id is null or empty
                    if (string.IsNullOrEmpty(entity.ServiceMetadata.Id))
                    {
                        if (TempIdToEntityMapping == null)
                        {
                            TempIdToEntityMapping = new Dictionary <string, IOfflineEntity>();
                        }
                        tempId = Guid.NewGuid().ToString();
                        TempIdToEntityMapping.Add(tempId, entity);
                    }

                    this._syncWriter.AddItem(entity, tempId);
                }

                this._syncWriter.WriteFeed(XmlWriter.Create(memoryStream));

                memoryStream.Flush();
                // Set the content length
                webRequest.ContentLength = memoryStream.Position;

                using (Stream requestStream = webRequest.GetRequestStream())
                {
                    CopyStreamContent(memoryStream, requestStream);

                    // Close the request stream
                    requestStream.Flush();
                    requestStream.Close();
                }
            }

            // Fire the Before request handler
            this.FirePreRequestHandler(webRequest);

            // Get the response
            HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();

            if (webResponse.StatusCode == HttpStatusCode.OK)
            {
                ChangeSetResponse changeSetResponse = new ChangeSetResponse();

                using (Stream responseStream = webResponse.GetResponseStream())
                {
                    // Create the SyncReader
                    this._syncReader = new ODataAtomReader(responseStream, this._knownTypes);

                    // Read the response
                    while (this._syncReader.Next())
                    {
                        switch (this._syncReader.ItemType)
                        {
                        case ReaderItemType.Entry:
                            IOfflineEntity entity      = this._syncReader.GetItem();
                            IOfflineEntity ackedEntity = entity;
                            string         tempId      = null;

                            // If conflict only one temp ID should be set
                            if (this._syncReader.HasTempId() && this._syncReader.HasConflictTempId())
                            {
                                throw new CacheControllerException(string.Format("Service returned a TempId '{0}' in both live and conflicting entities.",
                                                                                 this._syncReader.GetTempId()));
                            }

                            // Validate the live temp ID if any, before adding anything to the offline context
                            if (this._syncReader.HasTempId())
                            {
                                tempId = this._syncReader.GetTempId();
                                CheckEntityServiceMetadataAndTempIds(TempIdToEntityMapping, entity, tempId, changeSetResponse);
                            }

                            //  If conflict
                            if (this._syncReader.HasConflict())
                            {
                                Conflict       conflict       = this._syncReader.GetConflict();
                                IOfflineEntity conflictEntity = (conflict is SyncConflict) ?
                                                                ((SyncConflict)conflict).LosingEntity : ((SyncError)conflict).ErrorEntity;

                                // Validate conflict temp ID if any
                                if (this._syncReader.HasConflictTempId())
                                {
                                    tempId = this._syncReader.GetConflictTempId();
                                    CheckEntityServiceMetadataAndTempIds(TempIdToEntityMapping, conflictEntity, tempId, changeSetResponse);
                                }

                                // Add conflict
                                changeSetResponse.AddConflict(conflict);

                                //
                                // If there is a conflict and the tempId is set in the conflict entity then the client version lost the
                                // conflict and the live entity is the server version (ServerWins)
                                //
                                if (this._syncReader.HasConflictTempId() && entity.ServiceMetadata.IsTombstone)
                                {
                                    //
                                    // This is a ServerWins conflict, or conflict error. The winning version is a tombstone without temp Id
                                    // so there is no way to map the winning entity with a temp Id. The temp Id is in the conflict so we are
                                    // using the conflict entity, which has the PK, to build a tombstone entity used to update the offline context
                                    //
                                    // In theory, we should copy the service metadata but it is the same end result as the service fills in
                                    // all the properties in the conflict entity
                                    //

                                    // Add the conflict entity
                                    conflictEntity.ServiceMetadata.IsTombstone = true;
                                    ackedEntity = conflictEntity;
                                }
                            }

                            // Add ackedEntity to storage. If ackedEntity is still equal to entity then add non-conflict entity.
                            if (!String.IsNullOrEmpty(tempId))
                            {
                                changeSetResponse.AddUpdatedItem(ackedEntity);
                            }

                            break;

                        case ReaderItemType.SyncBlob:
                            changeSetResponse.ServerBlob = this._syncReader.GetServerBlob();
                            break;
                        }
                    }
                }

                if (TempIdToEntityMapping != null && TempIdToEntityMapping.Count != 0)
                {
                    // The client sent some inserts which werent ack'd by the service. Throw.
                    StringBuilder builder = new StringBuilder("Server did not acknowledge with a permanant Id for the following tempId's: ");
                    builder.Append(string.Join(",", TempIdToEntityMapping.Keys.ToArray()));
                    throw new CacheControllerException(builder.ToString());
                }

                this.FirePostResponseHandler(webResponse);

                webResponse.Close();

                return(changeSetResponse);
            }
            else
            {
                throw new CacheControllerException(
                          string.Format("Remote service returned error status. Status: {0}, Description: {1}",
                                        webResponse.StatusCode,
                                        webResponse.StatusDescription));
            }
        }
示例#9
0
        private object ProcessDownloadRequest(HttpWebRequest webRequest, CacheRequest request)
        {
            using (Stream memoryStream = new MemoryStream())
            {
                // Create a SyncWriter to write the contents
                this._syncWriter = new ODataAtomWriter(base.BaseUri);

                this._syncWriter.StartFeed(true, request.KnowledgeBlob ?? new byte[0]);

                this._syncWriter.WriteFeed(XmlWriter.Create(memoryStream));
                memoryStream.Flush();

                webRequest.ContentLength = memoryStream.Position;
                Stream requestStream = webRequest.GetRequestStream();
                CopyStreamContent(memoryStream, requestStream);

                requestStream.Flush();
                requestStream.Close();

                // Fire the Before request handler
                this.FirePreRequestHandler(webRequest);
            }

            // Get the response
            HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();

            if (webResponse.StatusCode == HttpStatusCode.OK)
            {
                ChangeSet changeSet = new ChangeSet();

                using (Stream responseStream = webResponse.GetResponseStream())
                {
                    // Create the SyncReader
                    this._syncReader = new ODataAtomReader(responseStream, this._knownTypes);

                    // Read the response
                    while (this._syncReader.Next())
                    {
                        switch (this._syncReader.ItemType)
                        {
                        case ReaderItemType.Entry:
                            changeSet.AddItem(this._syncReader.GetItem());
                            break;

                        case ReaderItemType.SyncBlob:
                            changeSet.ServerBlob = this._syncReader.GetServerBlob();
                            break;

                        case ReaderItemType.HasMoreChanges:
                            changeSet.IsLastBatch = !this._syncReader.GetHasMoreChangesValue();
                            break;
                        }
                    }

                    this.FirePostResponseHandler(webResponse);
                }

                webResponse.Close();

                return(changeSet);
            }
            else
            {
                throw new CacheControllerException(
                          string.Format("Remote service returned error status. Status: {0}, Description: {1}",
                                        webResponse.StatusCode,
                                        webResponse.StatusDescription));
            }
        }
        /// <summary>
        /// Callback for the Upload HttpWebRequest.BeginGetResponse call
        /// </summary>
        /// <param name="task">IAsyncResult object</param>
        async Task OnUploadGetResponseCompleted(Task <WebResponse> task, AsyncArgsWrapper wrapper)
        {
            wrapper.UploadResponse = new ChangeSetResponse();

            HttpWebResponse response = null;

            try
            {
                try
                {
                    response = await task.ConfigureAwait(false) as HttpWebResponse;
                }
                catch (WebException we)
                {
                    wrapper.UploadResponse.Error = we;
                    // If we get here then it means we completed the request. Return to the original caller
                    this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper);
                    return;
                }
                catch (SecurityException se)
                {
                    wrapper.UploadResponse.Error = se;
                    // If we get here then it means we completed the request. Return to the original caller
                    this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper);
                    return;
                }

                if (response.StatusCode == HttpStatusCode.OK)
                {
                    Stream responseStream = response.GetResponseStream();

                    // Create the SyncReader
                    this._syncReader = (base.SerializationFormat == ClientServices.SerializationFormat.ODataAtom)
                        ? (SyncReader) new ODataAtomReader(responseStream, this._knownTypes)
                        : (SyncReader) new ODataJsonReader(responseStream, this._knownTypes);

                    // Read the response
                    while (this._syncReader.Next())
                    {
                        switch (this._syncReader.ItemType)
                        {
                        case ReaderItemType.Entry:
                            IOfflineEntity entity      = this._syncReader.GetItem();
                            IOfflineEntity ackedEntity = entity;
                            string         tempId      = null;

                            // If conflict only one temp ID should be set
                            if (this._syncReader.HasTempId() && this._syncReader.HasConflictTempId())
                            {
                                throw new CacheControllerException(string.Format("Service returned a TempId '{0}' in both live and conflicting entities.",
                                                                                 this._syncReader.GetTempId()));
                            }

                            // Validate the live temp ID if any, before adding anything to the offline context
                            if (this._syncReader.HasTempId())
                            {
                                tempId = this._syncReader.GetTempId();
                                CheckEntityServiceMetadataAndTempIds(wrapper, entity, tempId);
                            }

                            //  If conflict
                            if (this._syncReader.HasConflict())
                            {
                                Conflict       conflict       = this._syncReader.GetConflict();
                                IOfflineEntity conflictEntity = (conflict is SyncConflict) ?
                                                                ((SyncConflict)conflict).LosingEntity : ((SyncError)conflict).ErrorEntity;

                                // Validate conflict temp ID if any
                                if (this._syncReader.HasConflictTempId())
                                {
                                    tempId = this._syncReader.GetConflictTempId();
                                    CheckEntityServiceMetadataAndTempIds(wrapper, conflictEntity, tempId);
                                }

                                // Add conflict
                                wrapper.UploadResponse.AddConflict(conflict);

                                //
                                // If there is a conflict and the tempId is set in the conflict entity then the client version lost the
                                // conflict and the live entity is the server version (ServerWins)
                                //
                                if (this._syncReader.HasConflictTempId() && entity.ServiceMetadata.IsTombstone)
                                {
                                    //
                                    // This is a ServerWins conflict, or conflict error. The winning version is a tombstone without temp Id
                                    // so there is no way to map the winning entity with a temp Id. The temp Id is in the conflict so we are
                                    // using the conflict entity, which has the PK, to build a tombstone entity used to update the offline context
                                    //
                                    // In theory, we should copy the service metadata but it is the same end result as the service fills in
                                    // all the properties in the conflict entity
                                    //

                                    // Add the conflict entity
                                    conflictEntity.ServiceMetadata.IsTombstone = true;
                                    ackedEntity = conflictEntity;
                                }
                            }

                            // Add ackedEntity to storage. If ackedEntity is still equal to entity then add non-conflict entity.
                            if (!String.IsNullOrEmpty(tempId))
                            {
                                wrapper.UploadResponse.AddUpdatedItem(ackedEntity);
                            }
                            break;

                        case ReaderItemType.SyncBlob:
                            wrapper.UploadResponse.ServerBlob = this._syncReader.GetServerBlob();
                            break;
                        }
                    }

                    if (wrapper.TempIdToEntityMapping != null && wrapper.TempIdToEntityMapping.Count != 0)
                    {
                        // The client sent some inserts which werent ack'd by the service. Throw.
                        StringBuilder builder = new StringBuilder("Server did not acknowledge with a permanent Id for the following tempId's: ");
                        builder.Append(string.Join(",", wrapper.TempIdToEntityMapping.Keys.ToArray()));
                        throw new CacheControllerException(builder.ToString());
                    }

                    wrapper.WebResponse = response;
                    // Invoke user code on the correct synchronization context.
                    this.FirePostResponseHandler(wrapper);
                }
                else
                {
                    wrapper.UploadResponse.Error = new CacheControllerException(
                        string.Format("Remote service returned error status. Status: {0}, Description: {1}",
                                      response.StatusCode,
                                      response.StatusDescription));
                }

                // If we get here then it means we completed the request. Return to the original caller
                this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper);
            }
            catch (Exception e)
            {
                if (ExceptionUtility.IsFatal(e))
                {
                    throw;
                }

                wrapper.Error = e;
                this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper);
            }
        }
示例#11
0
        void OnDownloadCompleted(object sender, NSUrlEventArgs e)
        {
            FileStream fileStream = null;
            string     filePath   = null;

            try {
                if (e.Error == null)
                {
                    filePath = e.FilePath.Replace("file://", "").Replace("%20", " ");

                    NSHttpUrlResponse response = (NSHttpUrlResponse)_currentTask.Response;
                    if (response != null)
                    {
                        HttpStatusCode code = (HttpStatusCode)response.StatusCode;
                        if (code == HttpStatusCode.OK)
                        {
                            NSDictionary headers = response.AllHeaderFields;
                            if (string.IsNullOrWhiteSpace(_behaviors.UserId))
                            {
                                _behaviors.UserId = headers ["userid"].ToString();
                            }
                            if (string.IsNullOrWhiteSpace(_behaviors.UserEmail))
                            {
                                _behaviors.UserEmail = headers ["email"].ToString();
                            }
                            ;
                            _behaviors.SaveUserSession();

                            if (File.Exists(filePath))
                            {
                                fileStream = File.OpenRead(filePath);

                                fileStream.Seek(0, SeekOrigin.Begin);
                                int contentLength;
                                if (!int.TryParse(headers ["unzippedcontentlength"].ToString(), out contentLength))
                                {
                                    contentLength = -1;
                                }
                                Stream responseStream = new ProgressStream(fileStream, contentLength, _behaviors.ReadProgressCallback);

                                // Create the SyncReader
                                _syncReader = (SyncReader) new ODataAtomReader(responseStream, _knownTypes);

                                _wrapper.DownloadResponse = new ChangeSet();

                                // Read the response
                                while (this._syncReader.Next())
                                {
                                    switch (this._syncReader.ItemType)
                                    {
                                    case ReaderItemType.Entry:
                                        _wrapper.DownloadResponse.AddItem(_syncReader.GetItem());
                                        break;

                                    case ReaderItemType.SyncBlob:
                                        _wrapper.DownloadResponse.ServerBlob = _syncReader.GetServerBlob();
                                        break;

                                    case ReaderItemType.HasMoreChanges:
                                        _wrapper.DownloadResponse.IsLastBatch = !_syncReader.GetHasMoreChangesValue();
                                        break;
                                    }
                                }
                            }
                            else
                            {
                                _wrapper.Error = new FileNotFoundException(String.Format("Downloaded data file not found! {0}, Description: {1}", e.FilePath, response.Description));
                            }
                        }
                        else
                        {
                            _wrapper.Error = new CacheControllerWebException(string.Format("Remote service returned error status. Status: {0}, Description: {1}", code, response.Description), code);
                        }
                    }
                    else
                    {
                        _wrapper.Error = new CacheControllerException("Response is null");
                    }
                }
                else
                {
                    NSHttpUrlResponse response = _currentTask.Response as NSHttpUrlResponse;
                    HandleError(e.Error, response);
                }

                // If we get here then it means we completed the request. Return to the original caller
                _workerManager.CompleteWorkRequest(_wrapper.WorkerRequest, _wrapper);
            } catch (Exception ex) {
                if (ExceptionUtility.IsFatal(ex))
                {
                    throw;
                }

                _wrapper.Error = ex;

                _workerManager.CompleteWorkRequest(_wrapper.WorkerRequest, _wrapper);
            } finally {
                if (fileStream != null)
                {
                    fileStream.Close();
                }

                if (filePath != null && File.Exists(filePath))
                {
                    File.Delete(filePath);
                }
            }
        }
示例#12
0
        void OnUploadCompleted(object sender, NSUrlEventArgs e)
        {
            _wrapper.UploadResponse = new ChangeSetResponse();

            FileStream fileStream = null;

            string filePath = null;

            try {
                if (e.Error == null)
                {
                    string            responseDescription = "response is  null";
                    NSHttpUrlResponse response            = (NSHttpUrlResponse)_currentTask.Response;
                    if (response != null)
                    {
                        responseDescription = response.Description;
                    }

                    filePath = e.FilePath.Replace("file://", "").Replace("%20", " ");
                    if (File.Exists(filePath))
                    {
                        fileStream = File.OpenRead(filePath);
                        fileStream.Seek(0, SeekOrigin.Begin);

                        // Create the SyncReader
                        _syncReader = (SyncReader) new ODataAtomReader(fileStream, _knownTypes);

                        // Read the response
                        while (_syncReader.Next())
                        {
                            switch (_syncReader.ItemType)
                            {
                            case ReaderItemType.Entry:
                                IOfflineEntity entity      = _syncReader.GetItem();
                                IOfflineEntity ackedEntity = entity;
                                string         tempId      = null;

                                if (_syncReader.HasTempId() && _syncReader.HasConflictTempId())
                                {
                                    throw new CacheControllerException(string.Format("Service returned a TempId '{0}' in both live and conflicting entities.",
                                                                                     _syncReader.GetTempId()));
                                }

                                if (_syncReader.HasTempId())
                                {
                                    tempId = _syncReader.GetTempId();
                                    CheckEntityServiceMetadataAndTempIds(entity, tempId);
                                }

                                if (_syncReader.HasConflict())
                                {
                                    Conflict       conflict       = _syncReader.GetConflict();
                                    IOfflineEntity conflictEntity = (conflict is SyncConflict) ?
                                                                    ((SyncConflict)conflict).LosingEntity : ((SyncError)conflict).ErrorEntity;

                                    if (this._syncReader.HasConflictTempId())
                                    {
                                        tempId = _syncReader.GetConflictTempId();
                                        CheckEntityServiceMetadataAndTempIds(conflictEntity, tempId);
                                    }

                                    _wrapper.UploadResponse.AddConflict(conflict);

                                    if (_syncReader.HasConflictTempId() && entity.ServiceMetadata.IsTombstone)
                                    {
                                        conflictEntity.ServiceMetadata.IsTombstone = true;
                                        ackedEntity = conflictEntity;
                                    }
                                }

                                if (!String.IsNullOrEmpty(tempId))
                                {
                                    _wrapper.UploadResponse.AddUpdatedItem(ackedEntity);
                                }

                                break;

                            case ReaderItemType.SyncBlob:
                                _wrapper.UploadResponse.ServerBlob = _syncReader.GetServerBlob();
                                break;
                            }
                        }

                        if (_wrapper.TempIdToEntityMapping != null && _wrapper.TempIdToEntityMapping.Count != 0)
                        {
                            StringBuilder builder = new StringBuilder("Server did not acknowledge with a permanent Id for the following tempId's: ");
                            builder.Append(string.Join(",", _wrapper.TempIdToEntityMapping.Keys.ToArray()));
                            throw new CacheControllerException(builder.ToString());
                        }
                    }
                    else
                    {
                        _wrapper.Error = new FileNotFoundException(String.Format("Downloaded data file not found! {0}, Description: {1}", e.FilePath, responseDescription));
                    }
                }
                else
                {
                    NSHttpUrlResponse response = _currentTask.Response as NSHttpUrlResponse;
                    HandleError(e.Error, response);
                }

                _workerManager.CompleteWorkRequest(_wrapper.WorkerRequest, _wrapper);
            } catch (Exception ex) {
                if (ExceptionUtility.IsFatal(ex))
                {
                    throw ex;
                }

                _wrapper.Error = ex;

                _workerManager.CompleteWorkRequest(_wrapper.WorkerRequest, _wrapper);
            } finally {
                if (fileStream != null)
                {
                    fileStream.Close();
                }

                if (filePath != null && File.Exists(filePath))
                {
                    File.Delete(filePath);
                }
            }
        }
示例#13
0
        /// <summary>
        /// Callback for the Upload HttpWebRequest.BeginGetResponse call
        /// </summary>
        private async Task ReadUploadResponse(HttpWebResponse response, AsyncArgsWrapper wrapper)
        {
            try
            {
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    Stream responseStream = response.GetResponseStream();

                    this.syncReader = (SerializationFormat == SerializationFormat.ODataAtom)
                        ? new ODataAtomReader(responseStream, this.knownTypes)
                        : (SyncReader) new ODataJsonReader(responseStream, this.knownTypes);

                    // Read the response
                    await Task.Factory.StartNew(() =>
                    {
                        while (syncReader.Next())
                        {
                            switch (syncReader.ItemType)
                            {
                            case ReaderItemType.Entry:
                                IOfflineEntity entity      = syncReader.GetItem();
                                IOfflineEntity ackedEntity = entity;
                                string tempId = null;

                                // If conflict only one temp ID should be set
                                if (syncReader.HasTempId() && syncReader.HasConflictTempId())
                                {
                                    throw new CacheControllerException(
                                        string.Format(
                                            "Service returned a TempId '{0}' in both live and conflicting entities.",
                                            syncReader.GetTempId()));
                                }

                                // Validate the live temp ID if any, before adding anything to the offline context
                                if (syncReader.HasTempId())
                                {
                                    tempId = syncReader.GetTempId();
                                    CheckEntityServiceMetadataAndTempIds(wrapper, entity, tempId);
                                }

                                //  If conflict
                                if (syncReader.HasConflict())
                                {
                                    Conflict conflict             = syncReader.GetConflict();
                                    IOfflineEntity conflictEntity = (conflict is SyncConflict)
                                                                            ? ((SyncConflict)conflict).LosingEntity
                                                                            : ((SyncError)conflict).ErrorEntity;

                                    // Validate conflict temp ID if any
                                    if (syncReader.HasConflictTempId())
                                    {
                                        tempId = syncReader.GetConflictTempId();
                                        CheckEntityServiceMetadataAndTempIds(wrapper, conflictEntity, tempId);
                                    }

                                    // Add conflict
                                    wrapper.UploadResponse.AddConflict(conflict);

                                    //
                                    // If there is a conflict and the tempId is set in the conflict entity then the client version lost the
                                    // conflict and the live entity is the server version (ServerWins)
                                    //
                                    if (syncReader.HasConflictTempId() && entity.GetServiceMetadata().IsTombstone)
                                    {
                                        //
                                        // This is a ServerWins conflict, or conflict error. The winning version is a tombstone without temp Id
                                        // so there is no way to map the winning entity with a temp Id. The temp Id is in the conflict so we are
                                        // using the conflict entity, which has the PK, to build a tombstone entity used to update the offline context
                                        //
                                        // In theory, we should copy the service metadata but it is the same end result as the service fills in
                                        // all the properties in the conflict entity
                                        //

                                        // Add the conflict entity
                                        conflictEntity.GetServiceMetadata().IsTombstone = true;
                                        ackedEntity = conflictEntity;
                                    }
                                }

                                // Add ackedEntity to storage. If ackedEntity is still equal to entity then add non-conflict entity.
                                if (!String.IsNullOrEmpty(tempId))
                                {
                                    wrapper.UploadResponse.AddUpdatedItem(ackedEntity);
                                }
                                break;

                            case ReaderItemType.SyncBlob:
                                wrapper.UploadResponse.ServerBlob = syncReader.GetServerBlob();
                                break;
                            }
                        }
                    });


                    if (wrapper.TempIdToEntityMapping != null && wrapper.TempIdToEntityMapping.Count != 0)
                    {
                        // The client sent some inserts which werent ack'd by the service. Throw.
                        var builder =
                            new StringBuilder(
                                "Server did not acknowledge with a permanent Id for the following tempId's: ");
                        builder.Append(string.Join(",", wrapper.TempIdToEntityMapping.Keys.ToArray()));
                        throw new CacheControllerException(builder.ToString());
                    }
                }
                else
                {
                    wrapper.UploadResponse.Error = new CacheControllerException(
                        string.Format("Remote service returned error status. Status: {0}, Description: {1}",
                                      response.StatusCode,
                                      response.StatusDescription));
                }
            }
            catch (Exception e)
            {
                if (ExceptionUtility.IsFatal(e))
                {
                    throw;
                }

                wrapper.Error = e;
            }
        }
示例#14
0
        void OnDownloadCompleted(object sender, NSUrlEventArgs e)
        {
            try
            {
                if (e.Error == null)
                {
                    _filePath = e.FilePath.Replace("file://", "").Replace("%20", " ");

                    NSHttpUrlResponse response = (NSHttpUrlResponse)_currentTask.Response;
                    if (response != null)
                    {
                        HttpStatusCode code = (HttpStatusCode)response.StatusCode;
                        if (code == HttpStatusCode.OK)
                        {
                            NSDictionary headers = response.AllHeaderFields;
                            if (string.IsNullOrWhiteSpace(_behaviors.UserId))
                            {
                                _behaviors.UserId = headers["userid"].ToString();
                            }
                            if (string.IsNullOrWhiteSpace(_behaviors.UserEmail))
                            {
                                _behaviors.UserEmail = headers["email"].ToString();
                            }
                            _behaviors.ResourceVersion = headers["resourceversion"].ToString();

                            _behaviors.SaveUserSession();

                            IIOContext io = IOContext.Current;
                            if (io.Exists(_filePath))
                            {
                                FileStream fileStream = io.FileStream(_filePath, FileMode.Open);

                                fileStream.Seek(0, SeekOrigin.Begin);
                                int contentLength;
                                if (!int.TryParse(headers["unzippedcontentlength"].ToString(), out contentLength))
                                {
                                    contentLength = -1;
                                }
                                Stream responseStream = new ProgressStream(fileStream, contentLength, _behaviors.ReadProgressCallback);

                                // CreateInstance the SyncReader
                                if (ApplicationContext.Current.Settings.BitMobileFormatterDisabled)
                                {
                                    _syncReader = new ODataAtomReader(responseStream, _knownTypes);
                                }
                                else
                                {
                                    _syncReader = new BMReader(responseStream, _knownTypes);
                                }

                                _wrapper.DownloadResponse      = new ChangeSet();
                                _wrapper.DownloadResponse.Data = GetDownloadedValues(_wrapper);
                            }
                            else
                            {
                                _wrapper.Error = new FileNotFoundException(String.Format("Downloaded data file not found! {0}, Description: {1}", e.FilePath, response.Description));
                            }
                        }
                        else
                        {
                            _wrapper.Error = new CacheControllerWebException(string.Format("Remote service returned error status. Status: {0}, Description: {1}", code, response.Description), code);
                        }
                    }
                    else
                    {
                        _wrapper.Error = new CacheControllerException("Response is null");
                    }
                }
                else
                {
                    var response = _currentTask.Response as NSHttpUrlResponse;
                    HandleError(e.Error, response);
                }

                // If we get here then it means we completed the request. Return to the original caller
                _workerManager.CompleteWorkRequest(_wrapper.WorkerRequest, _wrapper);
            }
            catch (Exception ex)
            {
                if (ExceptionUtility.IsFatal(ex))
                {
                    throw;
                }

                _wrapper.Error = ex;

                _workerManager.CompleteWorkRequest(_wrapper.WorkerRequest, _wrapper);
            }
        }
示例#15
0
        void OnUploadCompleted(object sender, NSUrlEventArgs e)
        {
            _wrapper.UploadResponse = new ChangeSetResponse();

            FileStream fileStream = null;

            string filePath = null;

            try
            {
                if (e.Error == null)
                {
                    string responseDescription = "response is  null";
                    var    response            = (NSHttpUrlResponse)_currentTask.Response;
                    if (response != null)
                    {
                        responseDescription = response.Description;
                    }

                    filePath = e.FilePath.Replace("file://", "").Replace("%20", " ");
                    IIOContext io = IOContext.Current;
                    if (io.Exists(filePath))
                    {
                        fileStream = io.FileStream(filePath, FileMode.Open);
                        fileStream.Seek(0, SeekOrigin.Begin);

                        // CreateInstance the SyncReader
                        if (ApplicationContext.Current.Settings.BitMobileFormatterDisabled)
                        {
                            _syncReader = new ODataAtomReader(fileStream, _knownTypes);
                        }
                        else
                        {
                            _syncReader = new BMReader(fileStream, _knownTypes);
                        }

                        // Read the response
                        while (_syncReader.Next())
                        {
                            switch (_syncReader.ItemType)
                            {
                            case ReaderItemType.Entry:
                                IOfflineEntity entity      = _syncReader.GetItem();
                                IOfflineEntity ackedEntity = entity;
                                string         tempId      = null;

                                if (_syncReader.HasTempId() && _syncReader.HasConflictTempId())
                                {
                                    throw new CacheControllerException(string.Format("Service returned a TempId '{0}' in both live and conflicting entities.",
                                                                                     _syncReader.GetTempId()));
                                }

                                if (_syncReader.HasTempId())
                                {
                                    tempId = _syncReader.GetTempId();
                                    CheckEntityServiceMetadataAndTempIds(entity, tempId);
                                }

                                if (_syncReader.HasConflict())
                                {
                                    Conflict       conflict       = _syncReader.GetConflict();
                                    IOfflineEntity conflictEntity = (conflict is SyncConflict) ?
                                                                    ((SyncConflict)conflict).LosingEntity : ((SyncError)conflict).ErrorEntity;

                                    if (_syncReader.HasConflictTempId())
                                    {
                                        tempId = _syncReader.GetConflictTempId();
                                        CheckEntityServiceMetadataAndTempIds(conflictEntity, tempId);
                                    }

                                    _wrapper.UploadResponse.AddConflict(conflict);

                                    if (_syncReader.HasConflictTempId() && entity.ServiceMetadata.IsTombstone)
                                    {
                                        conflictEntity.ServiceMetadata.IsTombstone = true;
                                        ackedEntity = conflictEntity;
                                    }
                                }

                                if (!String.IsNullOrEmpty(tempId))
                                {
                                    _wrapper.UploadResponse.AddUpdatedItem(ackedEntity);
                                }

                                break;

                            case ReaderItemType.SyncBlob:
                                _wrapper.UploadResponse.ServerBlob = _syncReader.GetServerBlob();
                                break;
                            }
                        }
                    }
                    else
                    {
                        _wrapper.Error = new FileNotFoundException(String.Format("Downloaded data file not found! {0}, Description: {1}", e.FilePath, responseDescription));
                    }
                }
                else
                {
                    var response = _currentTask.Response as NSHttpUrlResponse;
                    HandleError(e.Error, response);
                }

                _workerManager.CompleteWorkRequest(_wrapper.WorkerRequest, _wrapper);
            }
            catch (Exception ex)
            {
                if (ExceptionUtility.IsFatal(ex))
                {
                    throw;
                }

                _wrapper.Error = ex;

                _workerManager.CompleteWorkRequest(_wrapper.WorkerRequest, _wrapper);
            }
            finally
            {
                if (fileStream != null)
                {
                    fileStream.Close();
                }

                if (filePath != null)
                {
                    IOContext.Current.Delete(filePath);
                }
            }
        }