public override void CreateResource(HttpRequestMessage request, ResourceRootSingle resource) { foreach (var httpRequestModifier in HttpRequestModifiers) { httpRequestModifier.CreateResource(request, resource); } }
public async Task Update <TModel>(TModel model) { // guard from kunckleheads if (model == null) { throw new ArgumentNullException(nameof(model)); } ThrowIfUnmanaged(model); var patch = BuildPatch(model); // if nothing was updated, no need to continue if (patch == null) { return; } var allModels = ModelRegistry.IncludedModelsCreate(model); foreach (var newModel in allModels) { var newResource = BuildModelResource(newModel); // Update the model instance in the argument var initialize = newModel.GetType().GetInitializeMethod(); initialize.Invoke(newModel, new object[] { newResource, this }); } var includes = allModels.Select(ModelRegistry.GetResource).ToArray(); var originalResource = ModelRegistry.GetResource(model); var root = ResourceRootSingle.FromResource(patch, includes); var request = await HttpRequestBuilder.UpdateResource(originalResource, root); var response = await HttpClient.SendAsync(request).ConfigureAwait(false); HttpResponseListener.UpdateResource(response.StatusCode, originalResource, root); response.CheckStatusCode(); if (response.StatusCode == HttpStatusCode.OK) { var responseRoot = await response.GetContentModel <ResourceRootSingle>(JsonSettings); // Update the model instance in the argument var initialize = typeof(TModel).GetInitializeMethod(); initialize.Invoke(model, new object[] { responseRoot.Data, this }); Cache.Update(responseRoot.Data.Id, model); } else if (response.StatusCode == HttpStatusCode.NoContent) { ModelRegistry.ApplyPatch(model, patch); } // create and cache includes await Task.WhenAll(allModels.Select(x => Task.Run(() => { var resource = ModelRegistry.GetResource(x); Cache.Update(resource.Id, x); }))); }
private async Task <HttpContent> BuildHttpContent(ResourceRootSingle root) { /* The streaming approach appears to have reduced the memory footprint by a decent * margin (maybe a third). I suspect that StringContent just copies the string to a * MemoryStream anyway so we're only reducing that extra step of string to stream. */ //return new StringContent(root.ToJson(JsonSettings), Encoding.UTF8, JsonApiHeader); var serializer = JsonSerializer.CreateDefault(new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None }); var stream = new MemoryStream(); var sr = new StreamWriter(stream); var writer = new JsonTextWriter(sr); serializer.Serialize(writer, root); await writer.FlushAsync(); stream.Seek(0, SeekOrigin.Begin); var content = new StreamContent(stream); content.Headers.ContentType = new MediaTypeHeaderValue(JsonApiHeader) { CharSet = Encoding.UTF8.WebName }; return(content); }
public async Task <HttpRequestMessage> CreateResource(ResourceRootSingle root) { var request = new HttpRequestMessage(HttpMethod.Post, root.Data.Type); HttpRequestModifier?.CreateResource(request, root); // Allowing the RequestModifier to set custom content, if they really wanted to if (request.Content == null) { request.Content = await BuildHttpContent(root); } return(request); }
public async Task <HttpRequestMessage> UpdateResource(Resource resource, ResourceRootSingle root) { var request = new HttpRequestMessage(new HttpMethod("PATCH"), $"{root.Data.Type}/{root.Data.Id}"); HttpRequestModifier?.UpdateResource(request, resource, root); // Allowing the RequestModifier to set custom content, if they really wanted to if (request.Content == null) { request.Content = await BuildHttpContent(root); } return(request); }
public async Task Get__Given_ModelId__When_DataRetrieved__Then_CreateAndCacheModel (Guid modelId) { var uri = "http://www.test.com/"; var expectedRequest = new HttpRequestMessage(HttpMethod.Get, new Uri(uri)); var modelRegistry = CreateModelRegistry(typeof(BasicModel)); var resourceType = modelRegistry.GetResourceType <BasicModel>(); var mockRequestBuilder = new Mock <IHttpRequestBuilder>(); mockRequestBuilder .Setup(x => x.GetResource(modelId, resourceType, string.Empty)) .Returns(expectedRequest); var mockHandler = new MockRequestHandler(); mockHandler.Setup( new Uri(uri), request => { Assert.Same(expectedRequest, request); var root = ResourceRootSingle.FromResource( new Resource { Id = modelId, Type = modelRegistry.GetResourceType <BasicModel>() }); return(Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(JsonConvert.SerializeObject(root)) })); }); var mockCacheProvider = new Mock <ICacheProvider>(); var subject = CreateSubject( mockHandler, mockRequestBuilder.Object, mockCacheProvider.Object, modelRegistry); var result = await subject.Get <BasicModel>(modelId); Assert.NotNull(result); Assert.Equal(modelId, result.Id); mockCacheProvider.Verify(x => x.Update(modelId, result), Times.Once); }
public override void UpdateResource(HttpRequestMessage request, Resource originalResource, ResourceRootSingle patch) { foreach (var httpRequestModifier in HttpRequestModifiers) { httpRequestModifier.UpdateResource(request, originalResource, patch); } }
/// <summary> /// Called by requests to update a resource /// </summary> /// <param name="statusCode">Response status</param> /// <param name="originalResource">Resource being updated</param> /// <param name="patch">Resource patch</param> public virtual Task UpdateResource(HttpStatusCode statusCode, Resource originalResource, ResourceRootSingle patch) { // Do nothing return(Task.CompletedTask); }
/// <summary> /// Called by requests to create a resource /// </summary> /// <param name="statusCode">Whether Argo considers the response code successful.</param> /// <param name="resource">Resource being created</param> public virtual Task CreateResource(HttpStatusCode statusCode, ResourceRootSingle resource) { // Do nothing return(Task.CompletedTask); }
private async Task <TModel> Create <TModel>(Type rootModelType, object model) { ThrowIfDisposed(); // set Id if unset var modelId = model == null ? Guid.NewGuid() : ModelRegistry.GetOrCreateId(model); if (modelId == Guid.Empty) { modelId = Guid.NewGuid(); ModelRegistry.SetId(model, modelId); } // Create a new model instance if not already existing if (model == null) { model = Activator.CreateInstance <TModel>(); ModelRegistry.SetId(model, modelId); } if (ModelRegistry.IsManagedModel(model)) { throw new ManagedModelCreationException(model.GetType(), modelId); } // all unmanaged models in the object graph, including root var allModels = ModelRegistry.IncludedModelsCreate(model); foreach (var newModel in allModels) { var newResource = BuildModelResource(newModel); // Update the model instance in the argument var initialize = newModel.GetType().GetInitializeMethod(); initialize.Invoke(newModel, new object[] { newResource, this }); } var rootResource = ModelRegistry.GetResource(model); var includes = allModels.Where(x => x != model).Select(ModelRegistry.GetResource).ToArray(); if (Log.IsDebugEnabled()) { Log.Debug(() => $"preparing to POST {rootResource.Type}:{{{rootResource.Id}}}"); foreach (var include in includes) { Log.Debug(() => $"preparing to POST included {include.Type}:{{{include.Id}}}"); } } var root = ResourceRootSingle.FromResource(rootResource, includes); var request = await HttpRequestBuilder.CreateResource(root); var response = await HttpClient.SendAsync(request).ConfigureAwait(false); HttpResponseListener.CreateResource(response.StatusCode, root); response.CheckStatusCode(); if (response.StatusCode == HttpStatusCode.Created) { var responseRoot = await response.GetContentModel <ResourceRootSingle>(JsonSettings); // Update the model instance in the argument var initialize = rootModelType.GetInitializeMethod(); initialize.Invoke(model, new object[] { responseRoot.Data, this }); } // create and cache includes await Task.WhenAll(allModels.Select(x => Task.Run(() => { var resource = ModelRegistry.GetResource(x); Cache.Update(resource.Id, x); }))); return((TModel)model); }
/// <summary> /// Modifies requests to update a resource /// </summary> /// <param name="request"></param> /// <param name="originalResource">Resource being updated</param> /// <param name="patch">Resource patch</param> public virtual void UpdateResource(HttpRequestMessage request, Resource originalResource, ResourceRootSingle patch) { // Do nothing }
public override Task UpdateResource(HttpStatusCode statusCode, Resource originalResource, ResourceRootSingle patch) { Logger.Information("Patched {Id}. Status: {StatusCode}", patch.Data.Id, statusCode); return(Task.CompletedTask); }
public override Task CreateResource(HttpStatusCode statusCode, ResourceRootSingle resource) { Logger.Information("Created {Type}. Status: {StatusCode}", resource.Data.Type, statusCode); return(Task.CompletedTask); }
public void CreateResource(HttpStatusCode statusCode, ResourceRootSingle resource) { FireAndForget(HttpResponseListeners .Select(x => x.CreateResource(statusCode, resource))); }
public override void UpdateResource(HttpRequestMessage request, Resource originalResource, ResourceRootSingle patch) { // First check patch then check the original resource var eTag = patch.Data.GetMeta().SelectToken(EtagMetaPath) ?? originalResource.GetMeta().SelectToken(EtagMetaPath); if (eTag != null) { request.Headers.IfMatch.Add(GetEtagHeader(eTag.ToString())); } }
public void UpdateResource(HttpStatusCode statusCode, Resource originalResource, ResourceRootSingle patch) { FireAndForget(HttpResponseListeners .Select(x => x.UpdateResource(statusCode, originalResource, patch))); }
/// <summary> /// Modifies requests to create a resource /// </summary> /// <param name="request"></param> /// <param name="resource">Resource being created</param> public virtual void CreateResource(HttpRequestMessage request, ResourceRootSingle resource) { // Do nothing }