/// <summary> /// The handle request. /// </summary> /// <param name="request"> /// The request. /// </param> /// <param name="response"> /// The response. /// </param> /// <returns> /// The <see cref="Task"/>. /// </returns> /// <exception cref="NotImplementedException"> /// </exception> public async Task HandleRequest(IServerMessage request, IServerMessage response) { // Check if authentication passed if (request.User == null) { // Do nothing if this happens, the auth segement will have dealt // with this state } else if (!this._commands.ContainsKey(request.Message)) { response.Message = $"{request.Message}Error"; response.Body = ParserFactory.GetDataParser(request.DataType).SerializeData(new ErrorResponse() { Reason = $"The operation {request.Message} is not available on the server", Code = 100 }); } else { var commandResponse = await this._commands[request.Message].Execute(request); response.DataType = request.DataType; response.Body = commandResponse.Body; response.Message = commandResponse.Message; response.User = null; } // Check if there is a successor for this segment of the chain if (Successor != null) { await Successor.HandleRequest(request, response); } }
/// <summary> /// The generate response. /// </summary> /// <param name="request"> /// The request. /// </param> /// <returns> /// The <see cref="Task"/>. /// </returns> public async Task <IServerMessage> GenerateResponse(IServerMessage request) { var unitOfWork = new UnitOfWork(); var productList = unitOfWork.ProductRepository.GetAllProducts(); var productDtoList = new List <ProductDto>(); foreach (var product in productList) { productDtoList.Add(new ProductDto() { Id = product.Id, Weight = product.Weight, Sku = product.Sku, Name = product.Name, Description = product.Description, Price = product.Price, State = product.State, Width = product.Width, Height = product.Height, Depth = product.Depth }); } // Console.WriteLine(ParserFactory.GetDataParser(request.DataType).SerializeData(productDtoList)); return(new ServerMessage(request.Message + "Result", ParserFactory.GetDataParser(request.DataType).SerializeData(productDtoList))); }
/// <summary> /// The handle request. /// </summary> /// <param name="request"> /// The requst. /// </param> /// <param name="response"> /// The response. /// </param> /// <returns> /// The <see cref="Task"/>. /// </returns> public async Task HandleRequest(IServerMessage request, IServerMessage response) { var userOrionKey = ParserFactory.GetDataParser(request.DataType).ParseData <Key>(request.User); if (userOrionKey == null) { // Do something here to stop processing and return some error to the server to // inform the client that auth has failed. request.User = null; await this.Successor.HandleRequest(request, response); } var orionContext = new Orion(new DeleteMeLogger()) { Communicator = { ApiAuthenticator = new OrgStandardAuthenticator() { PublicKey = this.Config.SystemPublicKey, SecertKey = this.Config.SystemSecretKey } } }; // Set the authentication Information var user = await orionContext.CreateUserController().GetUserProfile(userOrionKey, "Zeus"); if (user?.Result?.Meta == null || !user.Result.Meta.Any(x => x.Key.Equals("UserType"))) { request.User = null; } else { // Parse the Orion user data into local user data var firstOrDefault = user.Result.Meta.FirstOrDefault(x => x.Key.Equals("UserType")); if (firstOrDefault != null) { var parsedUser = UserFactory.GetUser( (UserType) (Convert.ToInt32(firstOrDefault.Value))); parsedUser.Email = user.Result.Email; parsedUser.Firstname = user.Result.Firstname; parsedUser.Surname = user.Result.Surname; parsedUser.Phone = user.Result.Phone; request.User = ParserFactory.GetDataParser(request.DataType).SerializeData(parsedUser); } } // Check the user type which should be contained in User Meta. await this.Successor.HandleRequest(request, response); }
public void TestJsonParser() { var parser = ParserFactory.GetDataParser(DataType.Json); var sampleObject = new ErrorResponse() { Code = 0, Reason = "Unit testing" }; var sampleObjectAsString = parser.SerializeData(sampleObject); Assert.IsTrue(sampleObjectAsString.Contains("{\"Reason\":\"Unit testing\",\"Code\":0}")); var sampleObjectParsed = parser.ParseData <ErrorResponse>(sampleObjectAsString); Assert.IsTrue(sampleObjectParsed.Reason.Equals(sampleObject.Reason) && sampleObjectParsed.Code == sampleObject.Code); }
/// <summary> /// The generate response. /// </summary> /// <param name="request"> /// The request. /// </param> /// <param name="config"> /// The config. /// </param> /// <returns> /// The <see cref="Task"/>. /// </returns> public async Task <IServerMessage> GenerateResponse(IServerMessage request) { var unitOfWork = new UnitOfWork(); var productDto = ParserFactory.GetDataParser(request.DataType).ParseData <ProductDto>(request.Body); if (productDto == null) { return(new ServerMessage(request.Message + "Error", ParserFactory.GetDataParser(request.DataType).SerializeData(new ErrorResponse() { Code = 101, Reason = "Invalid DTO was provided" }))); } var product = unitOfWork.ProductRepository.GetOrDefault(productDto.Id); if (product == null) { return(new ServerMessage(request.Message + "Error", ParserFactory.GetDataParser(request.DataType).SerializeData(new ErrorResponse() { Code = 102, Reason = "Invalid ID provided for an entity in the database" }))); } return(new ServerMessage(request.Message + "Result", ParserFactory.GetDataParser(request.DataType).SerializeData(new ProductDto() { Id = product.Id, Weight = product.Weight, Sku = product.Sku, Name = product.Name, Description = product.Description, Price = product.Price, State = product.State, Width = product.Width, Height = product.Height, Depth = product.Depth }))); }
private static string ConvertErrorToString(ErrorResponse error, DataType responseFormat) { return(ParserFactory.GetDataParser(responseFormat).SerializeData(error)); }
public async Task <IServerMessage> GenerateResponse(IServerMessage request) { var orderDto = ParserFactory.GetDataParser(request.DataType).ParseData <OrderDto>(request.Body); var products = new List <Product>(); var stopWatch = new Stopwatch(); stopWatch.Start(); Parallel.ForEach(orderDto.Products.Select(x => x.Id).ToList(), (currentProductId) => { var unitOfWork = new UnitOfWork(); var product = unitOfWork.ProductRepository.GetOrDefault(currentProductId); if (product == null) { return; } lock (products) { products.Add(product); } }); stopWatch.Stop(); Console.WriteLine(stopWatch.Elapsed); if (products.Count < orderDto.Products.Count) { return(ErrorFactory.GetError(request.Message, 103, request.DataType)); } var itemsForfulfilment = new List <IItem>(); foreach (var product in products) { var bestItemPriority = -1; var availableItems = new UnitOfWork().ItemRepository.GetAvailableItemByProduct(product); var bestItem = availableItems.FirstOrDefault(); var itemLock = new object(); if (bestItem == null) { return(ErrorFactory.GetError(request.Message, 104, request.DataType)); } Parallel.ForEach(availableItems.Where(i => itemsForfulfilment.All(x => x.Id != i.Id)), (item) => { // This is executed in parallel because it may become the case in the future // that the algortihm that calculates the priority for a specifc product // is computationally expensive and as such this is a good candidate for // threading, although concurrently the gains are minimal if any! // It will also improve performance as the stock of a product grows // -- Strategy -- var itemPriority = product.Priority.CalculatePriority(item, product); lock (itemLock) { if (itemPriority > bestItemPriority) { bestItem = item; bestItemPriority = itemPriority; } } }); itemsForfulfilment.Add(bestItem); } // Now we need to make changes to the add them to the relevant sector and // update the state. Unit of work encapsulates all below operations var updateItems = new UnitOfWork(); foreach (var item in itemsForfulfilment) { item.State = ItemState.AwaitingPicker; item.QueuedTime = DateTime.Now; updateItems.ItemRepository.Update(item); } // Create the order and commit it to persistance var order = new Order() { Items = itemsForfulfilment, Status = OrderStatus.Recieved, ShippingAddress = orderDto.ShippingAddress }; updateItems.OrderRepository.Add(order); await updateItems.SaveChangesAsync(); // End of unit of work, changes have been saved // ------ // Lets inform the user that there order has been processed. We are going to use the // bridge in this case var customer = ParserFactory.GetDataParser(request.DataType).ParseData <Customer>(request.User); var communication = new UserCommunication() { Subject = "Order Update ", Endpoint = customer.Phone, Body = $" Hey {customer.Firstname}, your order has been placed successfully. Thanks for using Zeus Solutions." + $" Your order will be shipped to {orderDto.ShippingAddress}" }; // Use SMS to send order info - BRIDGE communication.CommunicationCommunicator = new SmsSender(); communication.Send(); return(new ServerMessage(request.Message + "Result", ParserFactory.GetDataParser(request.DataType).SerializeData(new OrderResultDto() { Success = true }))); }