public string AddUser(string UserName, string Balance, string jsonInput) { User user = null; string message = string.Empty; enumStatus status = enumStatus.Unknown; double balance = 0.0; try { if (!double.TryParse(Balance, out balance)) { message = string.Format("Error: Invalid Balance: {0}", Balance); } if (!string.IsNullOrEmpty(jsonInput)) { user = new User(jsonInput); } else { user = new User(UserName, balance); } if (MatchMeDB.Instance.UserTable.ContainsKey(user.UserName) || MatchMeDB.Instance.Users.ContainsKey(user.Id)) { string existingUser = MatchMeDB.Instance.UserTable[user.UserName].ToString(); message = string.Format("Error: duplicate user. Existing User: {0} New User (rejected): {1}", existingUser, user.ToString()); } if (string.IsNullOrEmpty(message)) { status = MatchMeDB.Instance.AddUser(user); if (status.Equals(enumStatus.UserAdded)) { message = string.Format("User Added: {0}", user.ToString()); } } } catch (Exception ex) { ServerLog.LogException(ex, string.Format("Add User: {0}", user.ToString())); message = ex.Message; status = enumStatus.UserAddFailed; } var result = new Dictionary <string, string> { { "status", status.ToString() }, { "message", message } }; return(JsonConvert.SerializeObject(result)); }
public void Start() { AppDomain.CurrentDomain.UnhandledException += (o, ea) => { if (ea.ExceptionObject is Exception) { ServerLog.LogException(ea.ExceptionObject as Exception, "Unhandled exception handler called"); } else { ServerLog.LogError("Unhandled exception handler called with unrecognized exception objhect"); } }; ServerLog.LogInfo("Starting MatchMe Host"); listener.Start(); listener.BeginGetContext(OnContext, null); }
private void ExceptionRespond(HttpListenerContext context, Exception e, int code, DateTime reqStartTime) { byte[] message = serverCharSet.GetBytes( string.Format("An {0} exception was thrown.\n{1}\n{2}", e.GetType(), e.Message, e.StackTrace)); ServerLog.LogException(e, "An exception was thrown rendering URL " + context.Request.Url); System.Threading.Interlocked.Add(ref totalBytesOut, message.Length); if (code == 500) { System.Threading.Interlocked.Increment(ref total500s); } else if (code == 550) { System.Threading.Interlocked.Increment(ref total550s); } Respond(context, message, code, reqStartTime, "text/plain"); }
private void Respond(HttpListenerContext context, byte[] buffer, int returnCode, DateTime reqStartTime, string contentType = "text/plain") { int len = buffer != null ? buffer.Length : 0; try { context.Response.AddHeader("Cache-Control", "no-cache"); context.Response.AddHeader("Content-Type", contentType); context.Response.AddHeader("Access-Control-Allow-Origin", "*"); context.Response.ContentEncoding = serverCharSet; context.Response.ContentLength64 = len; context.Response.StatusCode = returnCode; context.Response.OutputStream.Write(buffer, 0, len); context.Response.ContentType = contentType; ServerLog.LogHttpRequest(context.Request, returnCode, len, string.Empty, (int)((startTime - DateTime.Now).TotalMilliseconds)); System.Threading.Interlocked.Add(ref totalBytesOut, buffer.Length); System.Threading.Interlocked.Increment(ref total200s); } catch (HttpListenerException hle) { ServerLog.LogException(hle, "Exception while returning data to http client"); } }
private void OnContext(IAsyncResult ar) { DateTime reqStartTime = DateTime.Now; HttpListenerContext context; try { context = listener.EndGetContext(ar); } catch (HttpListenerException) { ServerLog.LogInfo("HttpListener has been shut down"); return; } if (!stopping) { listener.BeginGetContext(OnContext, null); } var processWebRequest = new Task(() => { System.Threading.Interlocked.Increment(ref totalRequests); byte[] json = null; int httpStatus = 200; string redirectUrl = null; string outContentType = "application/json"; try { string processor; string command; string jsonInput; string module; string contentType; string source; string agent; var args = ParseUrl(context.Request, out processor, out command, out jsonInput, out module, out contentType, out source, out agent); if (module == "test") { if (processor == "util") { if (command == "stats") { StatRespond(context, reqStartTime); } else if (command == "health") { HealthRespond(context, reqStartTime); } else { throw new ApplicationException(string.Format("Unknown util command: {0}", command)); } return; } } else if (module == "action") { string jsonString = actionProcessor.Execute(command, args, jsonInput, contentType, source, agent, out outContentType, out redirectUrl, out httpStatus); if (jsonString == null) { jsonString = ""; } json = Encoding.UTF8.GetBytes(jsonString); } else if (module == "db") { string jsonString = dataProcessor.Execute(command, args, jsonInput, contentType, source, agent, out outContentType, out redirectUrl, out httpStatus); if (jsonString == null) { jsonString = ""; } json = Encoding.UTF8.GetBytes(jsonString); } else { throw new ApplicationException(string.Format("Unknown module: {0}", module)); } } catch (Exception e) { ExceptionRespond(context, e, 500, reqStartTime); return; } if (redirectUrl != null) { RespondRedirect(context, redirectUrl); } else { Respond(context, json, httpStatus, reqStartTime, outContentType); } }); lock (runningTasks) { if (stopping) { Respond(context, serverCharSet.GetBytes("MatchMe is shutting down.") , 500, reqStartTime); return; } runningTasks.Add(processWebRequest); } processWebRequest.ContinueWith(t => { lock (runningTasks) { runningTasks.Remove(t); } if (t.IsFaulted) { ServerLog.LogException(t.Exception.InnerException, "Exception was unhandled in task"); } }); processWebRequest.Start(); }
public string PlaceAnOrder(string UserName, string UserId, string Symbol, string Volume, string Price, string OrderType, string OrderSide) { User user = null; string message = string.Empty; string userId = MatchMeDB.Instance.UserTable[Config.AdminUser].Id; enumStatus status = enumStatus.Unknown; enumSide orderside = enumSide.Invalid; enumOrderType ordertype = enumOrderType.Invalid; double price = 0.0; int volume = 0; bool exist = false; double requiredbalance = 0.0; double remainbalance = 0.0; string symbol = Symbol.ToUpper(); try { Symbol = Symbol.ToUpper(); if (!int.TryParse(Volume, out volume)) { message = string.Format("Error: Invalid Volume: {0}", volume); status = enumStatus.OrderPlaceError; } if (!status.Equals(enumStatus.OrderPlaceError) && !string.IsNullOrEmpty(symbol)) { List <Order> companies = MatchMeDB.Instance.OrderTable.ContainsKey(userId) ? MatchMeDB.Instance.OrderTable[userId] : new List <Order>(); exist = companies.Where(a => a.Symbol.Equals(symbol)).Count() > 0; if (!exist) { message = string.Format("Error: The Company does not exist {0}", symbol); status = enumStatus.OrderPlaceError; } } else { message = string.Format("Error: The Company does not exist {0}", symbol); status = enumStatus.OrderPlaceError; } if (!status.Equals(enumStatus.OrderPlaceError) && !Enum.TryParse(OrderSide, true, out orderside)) { message = string.Format("Error: Invalid Order Side: {0}", OrderSide); status = enumStatus.OrderPlaceError; } if (!status.Equals(enumStatus.OrderPlaceError) && !Enum.TryParse(OrderType, true, out ordertype)) { message = string.Format("Error: Invalid Order Type: {0}", OrderType); status = enumStatus.OrderPlaceError; } if (!status.Equals(enumStatus.OrderPlaceError) && ordertype.Equals(enumOrderType.Market)) { price = Exchange.Instance.GetMarketPrice(orderside, symbol, volume); } if (!status.Equals(enumStatus.OrderPlaceError) && ordertype.Equals(enumOrderType.Limit)) { if (!double.TryParse(Price, out price)) { message = string.Format("Error: Invalid Price: {0}", Price); status = enumStatus.OrderPlaceError; } if (!status.Equals(enumStatus.OrderPlaceError) && orderside.Equals(enumSide.Sell)) { price = (-1) * Math.Abs(price); } } if (!status.Equals(enumStatus.OrderPlaceError) && !string.IsNullOrEmpty(UserName)) { MatchMeDB.Instance.UserTable.TryGetValue(UserName, out user); if (user == null) { message = string.Format("Error: Can't retrieve the User from the db via the keys. UserName{0}, UserId{1}", UserName, UserId); status = enumStatus.OrderPlaceError; } } if (!status.Equals(enumStatus.OrderPlaceError) && string.IsNullOrEmpty(message) && exist) { if (price > 0) { //price larger than zero means that it's a buy limit order or an order with valid market price requiredbalance = price * volume + Config.Commission; } if (requiredbalance > user.Balance) { //check if balance is enough remainbalance = requiredbalance - user.Balance; message = string.Format("Error: No Enough Balance: Remain balance {0}, Requires {1} to place the order", user.Balance, remainbalance); status = enumStatus.Rejected; } else { Order newOrder = new Order(symbol, volume, price, user.Id, ordertype, orderside); if (orderside.Equals(enumSide.Sell)) { status = Exchange.Instance.PlaceSell(newOrder); if (status.Equals(enumStatus.Rejected)) { message = string.Format("Error: Short Sell is not allowed. {0}", newOrder); } } else if (orderside.Equals(enumSide.Buy)) { status = Exchange.Instance.PlaceBuy(newOrder); } if (!status.Equals(enumStatus.OrderPlaceError) && string.IsNullOrEmpty(message)) { message = "New Order Placed:" + MatchMeDB.Instance.Orders[newOrder.Id]; status = enumStatus.OrderPlaced; } } } } catch (Exception ex) { ServerLog.LogException(ex, string.Format("Place Order Failed, User {0}, Symbol {1}", user.ToString(), Symbol)); message = ex.Message; status = enumStatus.OrderPlaceError; } var result = new Dictionary <string, string> { { "status", status.ToString() }, { "message", message } }; return(JsonConvert.SerializeObject(result)); }
public string AddCompany(string Symbol, string Volume, string Price) { if (!MatchMeDB.Instance.UserTable.ContainsKey(Config.AdminUser)) { User user = new User(Config.AdminUser, 0.0); MatchMeDB.Instance.AddUser(user); } string message = string.Empty; double price = Config.DefaultPrice; int volume = Config.DefaultVolume; string userId = MatchMeDB.Instance.GetUserId(Config.AdminUser); var status = enumStatus.Unknown; enumOrderType ordertype; enumSide orderside; try { Symbol = Symbol.ToUpper(); if (string.IsNullOrEmpty(Price) || !double.TryParse(Price, out price)) { ServerLog.LogInfo(message); } if (string.IsNullOrEmpty(message) && (string.IsNullOrEmpty(Volume) || !int.TryParse(Volume, out volume))) { ServerLog.LogInfo(message); } List <Order> companies = MatchMeDB.Instance.OrderTable.ContainsKey(userId) ? MatchMeDB.Instance.OrderTable[userId] : new List <Order>(); foreach (Order company in companies) { if (company.Symbol.Equals(Symbol)) { message = string.Format("Error: duplicate company. Existing User: {0} New Company Symbol (rejected): {1}", company, Symbol); status = enumStatus.CompanyAddFailed; } } ordertype = enumOrderType.Market; orderside = enumSide.Sell; price = -Math.Abs(price); Order newOrder = new Order(Symbol, volume, price, userId, ordertype, orderside); if (string.IsNullOrEmpty(message) && Exchange.Instance.PlaceSell(newOrder, true).Equals(enumStatus.OrderPlaced)) { Position position = MatchMeDB.Instance.GetPosition(userId, Symbol); position.Quantity = volume; MatchMeDB.Instance.UpdatePosition(position); message = string.Format("Company Created: {0}, Volume: {1}, Price: {2}", newOrder.Symbol, newOrder.Volume, newOrder.Price); status = enumStatus.CompanyAdded; } } catch (Exception ex) { ServerLog.LogException(ex, string.Format("Add Company, Symbol {0}, Volume {1}, Price", Symbol, Volume, price.ToString())); message = ex.Message; status = enumStatus.CompanyAddFailed; } var result = new Dictionary <string, string> { { "status", status.ToString() }, { "message", message } }; return(JsonConvert.SerializeObject(result)); }
public string AdjustBalance(string UserName, string UserId, string AdjustAmount) { User user = null; string message = string.Empty; enumStatus status = enumStatus.Unknown; double adjustAmount; try { if (!double.TryParse(AdjustAmount, out adjustAmount)) { message = string.Format("Error: Invalid adjustment: {0}", adjustAmount); status = enumStatus.BalanceAdjustFailed; } if (!string.IsNullOrEmpty(UserName)) { MatchMeDB.Instance.UserTable.TryGetValue(UserName, out user); } if (user == null && !string.IsNullOrEmpty(UserId)) { string userDoc = string.Empty; MatchMeDB.Instance.Users.TryGetValue(UserId, out userDoc); if (userDoc != null) { user = new User(userDoc); } } if (user == null) { message = string.Format("Error: Can't retrieve the User from the db via the keys. UserName{0}, UserId{1}", UserName, UserId); status = enumStatus.BalanceAdjustFailed; } else { //We found the User in DB, so we update it! user.Balance += adjustAmount; if (user.Balance < 0) { message = string.Format("Error: Balance less than 0. UserName{0}, UserId{1}", UserName, user.Balance); status = enumStatus.BalanceAdjustFailed; } status = MatchMeDB.Instance.UpdateUser(user); if (status.Equals(enumStatus.BalanceAdjusted)) { message = string.Format("Balance Adjusted. {0}", user.ToString()); } } } catch (Exception ex) { ServerLog.LogException(ex, string.Format("Add User: {0}", user.ToString())); message = ex.Message; status = enumStatus.BalanceAdjustFailed; } var result = new Dictionary <string, string> { { "status", status.ToString() }, { "message", message } }; return(JsonConvert.SerializeObject(result)); }