public async Task ShouldValidateServiceRequest() { var wrongRequest = new TradeCreationRequest() { Counterparty = null, Asset = "XXXXXX", Price = 100.0, Volume = 100, Way = TradeWay.Buy }; var correctRequest = new TradeCreationRequest() { Counterparty = "XXXXXX", Asset = "XXXXXX", Price = 100.0, Volume = 100, Way = TradeWay.Buy }; Assert.CatchAsync(async() => { var error = await _tradeClient.CreateTrade(wrongRequest); }, "'Counterparty should be set'"); var result = await _tradeClient.CreateTrade(correctRequest); Assert.IsNotNull(result); Assert.IsNotNull(result.TradeId); await Task.Delay(1000); }
public async Task ShouldTestService() { var noAuthClient = ApiServiceBuilder <ITradeService> .Build("http://localhost:8080").Create(); var eqTraderClient = _tradeClient; var traderToken = ApiServiceBuilder <IUserService> .Build("http://localhost:8080") .Create() .Login(new Credentials() { Username = "******", Password = "******" }).Result; var tradeClient = ApiServiceBuilder <ITradeService> .Build("http://localhost:8080") .AddAuthorizationHeader(() => traderToken.Digest) .Create(); Assert.CatchAsync(async() => { await noAuthClient.GetAllTrades(); }, "Response status code does not indicate success: 403 (Forbidden)."); var trades = await tradeClient.GetAllTrades(); var request = new TradeCreationRequest() { Counterparty = "XXX", Asset = "XXX", Price = 100.0, Volume = 100, Way = TradeWay.Buy }; Assert.CatchAsync(async() => { await tradeClient.CreateTrade(request); }, "Response status code does not indicate success: 403 (Forbidden)."); var createdTradeResult = await eqTraderClient.CreateTrade(request); Assert.IsNotNull(createdTradeResult); var createdTrade = await eqTraderClient.GetTradeById(createdTradeResult.TradeId); Assert.IsNotNull(createdTrade); Assert.AreEqual(request.Counterparty, createdTrade.Counterparty); Assert.AreEqual(request.Asset, createdTrade.Asset); var client = new HttpClient(); var jsonError = await client.GetAsync("http://localhost:8080/api/v1/trade"); var error = JsonConvert.DeserializeObject <ServiceErrorModel>(await jsonError.Content.ReadAsStringAsync()); Assert.IsNotNull(error, "erroe should be send to the client in json format"); Assert.AreEqual("User must have role [Trader]", error.Details); Assert.AreEqual("Unauthorized", error.Reason); await Task.Delay(500); }
public async Task <ActionResult <TradeCreationResult> > CreateTrade([FromBody] TradeCreationRequest request) { var valid = this.ModelState.IsValid; var tradeResult = await Service.CreateTrade(request); return(CreatedAtAction(nameof(GetTradeById), new { tradeId = tradeResult.TradeId }, tradeResult)); }
public async Task <ActionResult <TradeCreationResult> > CreateTrade([FromBody] TradeCreationRequest request) { request.Trader = HttpContext.User.Identity.Name; var tradeResult = await Service.CreateTrade(request); return(CreatedAtAction(nameof(GetTradeById), new { tradeId = tradeResult.TradeId }, tradeResult)); }
public Task <TradeCreationResult> CreateTrade(TradeCreationRequest request) { var trade = new Trade(Guid.NewGuid(), DateTime.Now, request.Counterparty, request.Asset, TradeStatus.None, request.Way, request.Price, request.Volume); _repository.Add(trade); var result = new TradeCreationResult() { TradeId = trade.Id, TradeStatus = TradeStatus.Created }; return(Task.FromResult(result)); }
public async Task <TradeCreationResult> CreateTrade(TradeCreationRequest request) { var trade = await Service.CreateTrade(request); //run "compliance" on a "compliance service" Scheduler.Default.Schedule(async() => { //wait for the client to fetch the new trade... await Task.Delay(1000); //if signalr is still trying to get a running instance, just bypass the process... if (null == _tradeEventService.Current) { return; } await _tradeEventService.Current.Proxy.RaiseChange(new TradeEvent() { Status = TradeStatus.ComplianceCheck, TradeId = trade.TradeId }); if (request.Counterparty == TradeServiceReferential.HighLatencyCounterparty) { await Task.Delay(5000); } else { await Task.Delay(1000); } var status = TradeStatus.Processed; //reject 1/5 trades if (new Random().Next(1, 6) == 1) { status = TradeStatus.Rejected; } await _tradeEventService.Current.Proxy.RaiseChange(new TradeEvent() { Status = status, TradeId = trade.TradeId }); }); return(trade); }
public async Task <TradeCreationResult> CreateTrade(TradeCreationRequest request) { var trade = new Trade(); var tradeCreationEvent = new CreateTrade() { Asset = request.Asset, Currency = request.Currency, Volume = request.Volume, Way = request.Way, TradeService = _configuration.Id, Trader = request.Trader }; await _repository.Apply(trade, tradeCreationEvent); return(new TradeCreationResult() { TradeId = trade.EntityId }); }
public async Task ShouldTestResponseCache() { //response cache do not work with an auth header var tradeClient = ApiServiceBuilder <ITradeService> .Build("http://localhost:8080").Create(); var initialTrades = await tradeClient.GetAllTradesViaCache(); var request = new TradeCreationRequest() { Counterparty = "XXXXX", Asset = "XXXXX", Price = 100.0, Volume = 100, Way = TradeWay.Buy }; var createdTradeResult = await _tradeClient.CreateTrade(request); await Task.Delay(1000); var cachedTrades = await tradeClient.GetAllTradesViaCache(); var notCachedTrades = await _tradeClient.GetAllTrades(); Assert.AreEqual(initialTrades.Count(), cachedTrades.Count()); Assert.AreEqual(notCachedTrades.Count(), cachedTrades.Count() + 1); var tradeClientNoCache = ApiServiceBuilder <ITradeService> .Build("http://localhost:8080") .AddHeader("Cache-Control", () => "no-cache ") .Create(); //wait for the cache to invalidate await Task.Delay(3000); cachedTrades = await tradeClientNoCache.GetAllTradesViaCache(); Assert.AreEqual(notCachedTrades.Count(), cachedTrades.Count()); }
public MainViewModel() { Events = new ObservableCollection <string>(); Trades = new ObservableCollection <TradeViewModel>(); var configuration = AppCore.Instance.Get <AppConfiguration>(); var refitSettings = new RefitSettings() { ContentSerializer = new JsonContentSerializer(AppCore.Instance.Get <JsonSerializerSettings>()), HttpMessageHandlerFactory = () => new HttpRetryForeverMessageHandler(5000) }; _tradeService = ApiServiceBuilder <ITradeService> .Build(configuration.Gateway) .AddAuthorizationHeader(() => { return(_token.AccessToken); }) .Create(refitSettings: refitSettings); MakeTrade = new Command(async() => { var asset = TradeServiceReferential.Assets.Random(); var counterparty = TradeServiceReferential.Counterparties.Random(); var rand = new Random(); var request = new TradeCreationRequest() { Asset = asset.Name, Volume = rand.Next(1, 50), Way = TradeWay.Buy }; var tradeEvent = await _tradeService.CreateTrade(request); var trade = await _tradeService.GetTradeById(tradeEvent.TradeId); Notify($"{_token.User.Identity.Name} created trade {trade.EntityId} on desktop UI"); }); var options = new OidcClientOptions() { Authority = configuration.Identity, ClientId = AzurePlaygroundConstants.Auth.ClientOpenIdNative, Scope = "openid profile desk trade", Policy = new Policy { Discovery = new DiscoveryPolicy { RequireHttps = false } }, RedirectUri = "http://127.0.0.1/sample-wpf-app", PostLogoutRedirectUri = "http://127.0.0.1/sample-wpf-app", ResponseMode = OidcClientOptions.AuthorizeResponseMode.FormPost, Flow = OidcClientOptions.AuthenticationFlow.AuthorizationCode, Browser = new WpfEmbeddedBrowser() }; _oidcClient = new OidcClient(options); Login = new Command(async() => { try { _token = await _oidcClient.LoginAsync(new IdentityModel.OidcClient.LoginRequest()); } catch (Exception ex) { Notify(ex.ToString()); return; } if (_token.IsError) { var error = _token.Error == "User Cancellled" ? "The sign-in window was closed before authorization was completed." : _token.Error; Notify(error); } else { Token = _token; Notify($"Logged in as { _token.User.Identity.Name}"); _priceEventService = SignalRServiceBuilder <Price, PriceRequest> .Create() .Build(new PriceRequest((p) => true), (opts) => { opts.AccessTokenProvider = () => Task.FromResult(_token.AccessToken); }); var priceServiceConnection = _priceEventService .Connect(Scheduler.Default, 1000) .Subscribe((priceEvent) => { lock (_locker) { if (null == Application.Current.Dispatcher) { return; } foreach (var trade in Trades.Where(trade => trade.Asset == priceEvent.Asset).ToList()) { Application.Current.Dispatcher.Invoke(() => trade.CurrentPrice = priceEvent.Value); } } var ev = MakeEvent("PRICE", "PRICE", priceEvent.Asset, priceEvent.Value); this.Notify(ev); }); _tradeEventService = SignalRServiceBuilder <Trade, TradeEventRequest> .Create() .Build(new TradeEventRequest((p) => true), (opts) => { opts.AccessTokenProvider = () => Task.FromResult(_token.AccessToken); }); var tradeEventServiceConnection = _tradeEventService .Connect(Scheduler.Default, 500) .Subscribe((tradeEvent) => { lock (_locker) { if (null == Application.Current.Dispatcher) { return; } Application.Current.Dispatcher.Invoke(() => { var trade = Trades.FirstOrDefault(t => t.Id == tradeEvent.EntityId); if (null == trade) { Trades.Add(new TradeViewModel(tradeEvent)); } else { trade.ApplyChange(tradeEvent); } }); } this.Notify(MakeEvent("TRADE", _tradeEventService.Current.Endpoint, tradeEvent.EntityId, tradeEvent.EntityId)); }); _cleanup.Add(priceServiceConnection); //_cleanup.Add(tradeEventServiceConnection); if (null == Application.Current.Dispatcher) { return; } await Application.Current.Dispatcher.Invoke(async() => { var trades = await _tradeService.GetAllTrades(); foreach (var trade in trades) { var vm = new TradeViewModel(trade); Trades.Add(vm); } Notify($"Fetched {trades.Count()} trade(s)"); }); } }, () => Token == null); Dispatcher.CurrentDispatcher.ShutdownStarted += (s, e) => { _cleanup.Dispose(); }; //Logout = new Command(async() => //{ // try // { // var request = new LogoutRequest // { // IdTokenHint = Token.IdentityToken // }; // await _oidcClient.LogoutAsync(request); // Token = null; // Notify($"Logged out"); // } // catch (Exception ex) // { // Notify(ex.ToString()); // return; // } //}); }
public MainViewModel() { Events = new ObservableCollection <string>(); _authService = ApiServiceBuilder <IUserService> .Build(TradeServiceReferential.ServiceHost) .Create(); _userToken = _authService.Login(new Credentials() { Username = "******", Password = "******" }).Result; AppCore.Instance.ObjectProvider.Configure(config => config.For <TradeServiceToken>().Use(_userToken)); _tradeService = ApiServiceBuilder <ITradeService> .Build(TradeServiceReferential.ServiceHost) .AddAuthorizationHeader(() => _userToken.Digest) .Create(); _priceEventService = SignalRServiceBuilder <Price, PriceRequest> .Create() .Build(new PriceRequest((p) => true), (opts) => { opts.AccessTokenProvider = () => Task.FromResult(_userToken.Digest); }); _priceEventService .Connect(Scheduler.Default, 1000) .Subscribe((priceEvent) => { foreach (var trade in Trades.Where(trade => trade.Asset == priceEvent.Asset).ToList()) { Application.Current.Dispatcher.Invoke(() => trade.CurrentPrice = priceEvent.Value); } var ev = MakeEvent("PRICE", "PRICE", priceEvent.Asset, priceEvent.Value); this.Notify(ev); }); _tradeEventService = SignalRServiceBuilder <TradeEvent, TradeEventRequest> .Create() .Build(new TradeEventRequest((p) => true), (opts) => { opts.AccessTokenProvider = () => Task.FromResult(_userToken.Digest); }); _tradeEventService .Connect(Scheduler.Default, 500) .Subscribe((tradeEvent) => { Application.Current.Dispatcher.Invoke(() => { var trade = Trades.FirstOrDefault(t => t.Id == tradeEvent.TradeId); if (null == trade) { return; } trade.Status = tradeEvent.Status; }); this.Notify(MakeEvent("TRADE", _tradeEventService.Current.Endpoint, tradeEvent.TradeId, tradeEvent.Status)); }); Trades = new ObservableCollection <TradeViewModel>(); MakeTrade = new Command(async() => { var asset = TradeServiceReferential.Assets.Random(); var counterparty = TradeServiceReferential.Counterparties.Random(); var rand = new Random(); var request = new TradeCreationRequest() { Counterparty = counterparty, Asset = asset.Name, Price = asset.Price, Volume = rand.Next(1, 50), Way = TradeWay.Buy }; var tradeEvent = await _tradeService.CreateTrade(request); var trade = await _tradeService.GetTradeById(tradeEvent.TradeId); Application.Current.Dispatcher.Invoke(() => Trades.Add(new TradeViewModel(trade))); }); Application.Current.Dispatcher.Invoke(async() => { var trades = await _tradeService.GetAllTrades(); foreach (var trade in trades) { var vm = new TradeViewModel(trade); Trades.Add(vm); } }); }