/// <summary> /// Enqueues the specified item. /// </summary> /// <param name="item">The item.</param> public new void Enqueue(RestfulObject <T> item) { lock (syncLock) // Enqueue is locked until current queue is empted by AttemptNextTransaction() { //Device.Log.Debug("Enqueue Item: item: " + item.Object.ToString() + " type: " + typeof(T).ToString() ); RestfulObject <T> queueitem = this.FirstOrDefault(exitem => exitem.UriEndpoint == item.UriEndpoint); if (queueitem != null) { if (item.Verb == HttpVerb.Delete) { queueitem.Verb = HttpVerb.Delete; //queueitem.Verb = HttpVerb.None; //base.Enqueue(item); } else { queueitem.Object = item.Object; } } else { base.Enqueue(item); } } TriggerTimer(); }
/// <summary> /// Creates a copy of a RESTful object for the item instance provided. /// </summary> /// <param name="domainObject">The item instance to clone to a new RESTful object.</param> /// <returns></returns> public RestfulObject <T> Clone(T domainObject) { RestfulObject <T> restObj = new RestfulObject <T>(domainObject, this.UriEndpoint) { ExpirationDate = this.ExpirationDate, LazyLoaded = this.LazyLoaded, Verb = this.Verb, AttemptRefreshDate = this.AttemptRefreshDate }; return(restObj); }
private Dictionary <string, string> MergeHeaders(RestfulObject <T> restObject) { var mergedHeaders = new Dictionary <string, string>(); if (Device.RequestInjectionHeaders != null) { mergedHeaders.AddRange(Device.RequestInjectionHeaders); } if (restObject != null && restObject.PutPostDeleteHeaders != null) { mergedHeaders.AddRange(restObject.PutPostDeleteHeaders); } return(mergedHeaders); }
private HttpStatusCode MakeRequest(RestfulObject <T> obj, out RestfulObject <T> responseObj) { //ISerializer<T> iSerializer = SerializerFactory.Create<T>( QueueSerializationFormat ); //Device.Log.Debug (string.QueueSerializationFormat ("Request Body: {0}", iSerializer.SerializeObject (obj.Object, MonoCross.Utilities.EncryptionMode.NoEncryption))); byte[] postBytes = Serializer.SerializeObjectToBytes(obj.Object, EncryptionMode.NoEncryption); var headers = MergeHeaders(obj); var body = Serializer.SerializeObject(obj.Object); // add OData Accept header if (Format == SerializationFormat.ODATA && !obj.PutPostDeleteHeaders.Contains("Accept")) { obj.PutPostDeleteHeaders.Add("Accept", "application/json"); } NetworkResponse retval = Device.Network.Poster.PostBytes(BaseUri.AppendPath(obj.TransactionEndpoint), postBytes, Serializer.ContentType, obj.Verb, headers, obj.Object, _responseTimeout); // if Rest returns type and verb Put/Post then convert response to type T // and call event with object to pass to subscriber (e.g. a provider) responseObj = default(RestfulObject <T>); if (retval.StatusCode == HttpStatusCode.OK || retval.StatusCode == HttpStatusCode.Created || retval.StatusCode == HttpStatusCode.Accepted || retval.StatusCode == HttpStatusCode.NoContent) { if (RequestReturnsObject) { if (obj.Verb == HttpVerb.Post || (obj.Verb == HttpVerb.Put && Format != SerializationFormat.ODATA)) { obj.ExpirationDate = retval.Expiration; obj.AttemptRefreshDate = retval.AttemptToRefresh; if (retval.ResponseBytes != null) { T returnObj = Serializer.DeserializeObject(retval.ResponseBytes, EncryptionMode.NoEncryption); if (returnObj == null) { responseObj = obj.Clone(returnObj); return(retval.StatusCode); } responseObj = obj.Clone(returnObj); } else { responseObj = obj.Clone(default(T)); } } else if (obj.Verb == HttpVerb.Delete || (obj.Verb == HttpVerb.Put && Format == SerializationFormat.ODATA)) { responseObj = obj.Clone(obj.Object); // set response object to return if DELETE or OData PUT } } else { responseObj = obj.Clone(obj.Object); obj.ExpirationDate = retval.Expiration; obj.AttemptRefreshDate = retval.AttemptToRefresh; } //if ( RequestReturnsObject && ( obj.Verb == HttpVerb.Post || obj.Verb == HttpVerb.Put ) ) //{ // T returnObj = iSerializer.DeserializeObject( retval.ResponseString, Core.Utilities.EncryptionMode.NoEncryption ); // if ( returnObj == null ) // return retval.StatusCode; // obj.ExpirationDate = retval.Expiration; // obj.AttemptRefreshDate = retval.AttemptToRefresh; // responseObj = obj.Clone( returnObj ); //} } return(retval.StatusCode); }
/// <summary> /// Attempts the next transaction. /// </summary> public void AttemptNextTransaction() { HttpStatusCode statusCode; bool exitLoop = false; lock (syncLock) { Device.Log.Debug(string.Format("AttemptNextTransaction: count {0} exitloop: {1} ", this.Count, exitLoop)); int qCount = this.Count; if (qCount <= 0) { return; } while (this.Count > 0 && !exitLoop) { RestfulObject <T> nextItem = Peek(); if (nextItem == null || nextItem.Verb == HttpVerb.None) { Device.Log.Debug(string.Format("AttemptNextTransaction: next item is null or Verb == None")); Dequeue(); continue; } try { Device.Log.Debug("Make Post Request: item: " + nextItem.Object.ToString() + " type: " + typeof(T).ToString()); RestfulObject <T> responseItem; statusCode = MakeRequest(nextItem, out responseItem); switch (statusCode) { case HttpStatusCode.OK: case HttpStatusCode.Created: case HttpStatusCode.Accepted: case HttpStatusCode.NoContent: Device.Log.Debug("Queue Processing Success: result status " + statusCode.ToString() + " item: " + nextItem.ToString() + " type: " + typeof(T).ToString()); Dequeue(); SerializeQueue(); if (OnRequestComplete != null && responseItem != null) { OnRequestComplete(responseItem, responseItem.Verb); } break; case HttpStatusCode.Unauthorized: case HttpStatusCode.ServiceUnavailable: case HttpStatusCode.RequestTimeout: case HttpStatusCode.BadGateway: case HttpStatusCode.GatewayTimeout: case (HttpStatusCode)(-1): // application exception from post case (HttpStatusCode)(-2): // no response object from post Device.Log.Debug("Halt Queue Processing: item: " + nextItem.ToString() + " type: " + typeof(T).ToString()); // do not remove from queue but halt processing to prevent repeated calls to server until authorized exitLoop = true; if (OnRequestError != null) { OnRequestError(nextItem, nextItem.Verb, statusCode); } if (DequeueOnError) { Device.Log.Debug("Removing Object From Queue: item: " + nextItem.ToString() + " type: " + typeof(T).ToString()); Dequeue(); SerializeQueue(); } continue; //break; default: Device.Log.Debug(string.Format("Restful Queue<{0}>: Received Status {1} for {2} to {3}. Removing from Queue.", typeof(T).Name, statusCode, nextItem.Verb, nextItem.TransactionEndpoint)); if (OnRequestError != null) { OnRequestError(nextItem, nextItem.Verb, statusCode); } Dequeue(); SerializeQueue(); break; } } catch (Exception exc) { if (OnRequestFailed != null) { OnRequestFailed(nextItem, nextItem.Verb, exc); } } } } }