Пример #1
0
        public ThrottledClient(int maxCount, TimeSpan resetSpan)
        {
            if (maxCount < 1)
            {
                throw new ArgumentOutOfRangeException("maxCount", "maxCount should be bigger than 0.");
            }

            _throttler = new Throttler(maxCount, resetSpan);
        }
Пример #2
0
        public void ThrottledMetthodIsCalledOnTimeout()
        {
            // arrange
            throttled = new Throttler<int>(Reseter, 100, TimeSpan.FromMilliseconds(200));

            // test
            throttled.Call(new int());
            throttled.Call(new List<int>());

            // assert
            Assert.IsTrue(waiter.WaitOne(2000));
            Assert.IsTrue(length == 1);
            Assert.IsFalse(waiter.WaitOne(2000));
        }
Пример #3
0
        public void ThrottledMetthodIsCalledOnFlush()
        {
            // arrange
            throttled = new Throttler<int>(Reseter, 100, TimeSpan.FromMinutes(5));

            // test
            throttled.Call(new int());
            throttled.Call(new int());
            throttled.Call(new int());
            throttled.Call(new List<int>());
            throttled.Flush();

            // assert
            Assert.IsTrue(waiter.WaitOne(2000));
            Assert.IsTrue(length == 3);
        }
Пример #4
0
        public void ThrottledMetthodIsCalledOnQueueFull()
        {
            // arrange
            throttled = new Throttler<int>(Reseter, 100, TimeSpan.FromMinutes(5));
            throttled.Call(new Fixture().CreateMany<int>(99).ToList());

            // assert 1
            Assert.IsFalse(waiter.WaitOne(2000));

            // test
            throttled.Call(new int());

            // assert 2
            Assert.IsTrue(waiter.WaitOne(2000));
            Assert.IsTrue(length == 100);
        }
Пример #5
0
        public AwesomeGrid()
        {
            InitializeComponent();
            this.grid.DoubleClick += Grid_DoubleClick;
            this.grid.KeyDown += Grid_KeyDown;
            this.grid.PreviewKeyDown += Grid_PreviewKeyDown;
            this.grid.ContextMenuNeeded += Grid_ContextMenuNeeded;
            this.grid.SelectionChanged += Grid_SelectionChanged;

            this.Click += AwesomeGrid_Click;
            this.tableLayout.Click += AwesomeGrid_Click;
            this.CaptionLabel.Click += AwesomeGrid_Click;

            _searchThrottle = new Throttler(this, 200, () =>
                {
                    _filter = SearchTextBox.Text;
                    UpdateFilter();
                }
            );
        }
Пример #6
0
        public void ThrottlerWorkTest()
        {
            DependencyContext.Using<ILocalCache>((c, cache) =>
            {
                object hitInfo = null;
                A.CallTo(() => cache.Add(A<string>.Ignored, A<object>.Ignored, A<TimeSpan>.Ignored))
                    .Invokes((s) => hitInfo = s.Arguments[1]);
                A.CallTo(() => cache.Get<object>(A<string>.Ignored)).ReturnsLazily(() => hitInfo);
                A.CallTo(() => cache.Remove(A<string>.Ignored)).Invokes(() => hitInfo = null);
                A.CallTo(() => c.Resolver.Resolve<ILocalCache>()).Returns(cache);

                var throttler = new Throttler("test", TimeSpan.Zero, 2);
                Assert.True(throttler.Check());
                Assert.True(throttler.Check());
                Assert.False(throttler.Check());
                hitInfo = null;
                Assert.True(throttler.Check());
                Assert.True(throttler.Check());
                Assert.False(throttler.Check());
                throttler.Reset();
                Assert.True(throttler.Check());
            });
        }
Пример #7
0
 public WooCommerceProductsService(WooCommerceConfig config, Throttler throttler)
     : base(config, throttler)
 {
     _serviceUrl = base.WCObject.ProductApiUrl;
 }
        private bool ValidateExistingUser(ref string username, string password, UserDefinition user)
        {
            username = user.Username;

            if (user.IsActive != 1)
            {
                if (Log.IsInfoEnabled)
                {
                    Log.Error(String.Format("Inactive user login attempt: {0}", username), this.GetType());
                }

                return(false);
            }

            // prevent more than 50 invalid login attempts in 30 minutes
            var throttler = new Throttler("ValidateUser:"******"site" || user.Source == "sign" || directoryService == null)
            {
                if (validatePassword())
                {
                    throttler.Reset();
                    return(true);
                }

                return(false);
            }

            if (user.Source != "ldap")
            {
                throw new ArgumentOutOfRangeException("userSource");
            }

            if (!string.IsNullOrEmpty(user.PasswordHash) &&
                user.LastDirectoryUpdate != null &&
                user.LastDirectoryUpdate.Value.AddHours(1) >= DateTime.Now)
            {
                if (validatePassword())
                {
                    throttler.Reset();
                    return(true);
                }

                return(false);
            }

            DirectoryEntry entry;

            try
            {
                entry = directoryService.Validate(username, password);
                if (entry == null)
                {
                    return(false);
                }

                throttler.Reset();
            }
            catch (Exception ex)
            {
                Log.Error("Error on directory access", ex, this.GetType());

                // couldn't access directory. allow user to login with cached password
                if (!user.PasswordHash.IsTrimmedEmpty())
                {
                    if (validatePassword())
                    {
                        throttler.Reset();
                        return(true);
                    }

                    return(false);
                }

                throw;
            }

            try
            {
                string salt        = user.PasswordSalt.TrimToNull();
                var    hash        = UserRepository.GenerateHash(password, ref salt);
                var    displayName = entry.FirstName + " " + entry.LastName;
                var    email       = entry.Email.TrimToNull() ?? user.Email ?? (username + "@yourdefaultdomain.com");

                using (var connection = SqlConnections.NewFor <UserRow>())
                    using (var uow = new UnitOfWork(connection))
                    {
                        var fld = UserRow.Fields;
                        new SqlUpdate(fld.TableName)
                        .Set(fld.DisplayName, displayName)
                        .Set(fld.PasswordHash, hash)
                        .Set(fld.PasswordSalt, salt)
                        .Set(fld.Email, email)
                        .Set(fld.LastDirectoryUpdate, DateTime.Now)
                        .WhereEqual(fld.UserId, user.UserId)
                        .Execute(connection, ExpectedRows.One);

                        uow.Commit();

                        UserRetrieveService.RemoveCachedUser(user.UserId, username);
                    }

                return(true);
            }
            catch (Exception ex)
            {
                Log.Error("Error while updating directory user", ex, this.GetType());
                return(true);
            }
        }
Пример #9
0
 public EtsyItemsService(string applicationKey, string sharedSecret, EtsyConfig config, Throttler throttler)
     : base(applicationKey, sharedSecret, config, throttler)
 {
 }
Пример #10
0
 public SceneSerializer(IFileSystem fs, Throttler throttler)
 {
     _fs        = fs ?? throw new ArgumentNullException(nameof(fs));
     _throttler = throttler ?? throw new ArgumentNullException(nameof(throttler));
 }
Пример #11
0
 public PacketHandler()
 {
     Throttler = new Throttler(10, 500);
     Device    = new Device(this);
 }
Пример #12
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ClusterViewModel"/> class.
        /// </summary>
        /// <param name="viewFactory">Factory for creating child windows.</param>
        /// <param name="matches">The clusters.</param>
        /// <param name="providers">Database access provider</param>
        /// <param name="rawProvider">Provider for LCMSRun for access to PBF files.</param>
        public ClusterViewModel(IClusterViewFactory viewFactory, List <ClusterMatch> matches, FeatureDataAccessProviders providers, ScanSummaryProviderCache rawProvider)
        {
            this.viewFactory                 = viewFactory;
            this.providers                   = providers;
            this.dbLock                      = new object();
            this.throttler                   = new Throttler(TimeSpan.FromMilliseconds(500));
            this.XicPlotViewModel            = new XicPlotViewModel(rawProvider);
            this.ClusterFeaturePlotViewModel = new ClusterFeaturePlotViewModel();
            this.Matches                     = new ObservableCollection <ClusterMatch>(matches ?? new List <ClusterMatch>());
            var clusters = this.Matches.Select(match => match.Cluster).ToList();

            this.rawProvider = rawProvider;

            this.SettingsCommand = new RelayCommand(() => this.viewFactory.CreateSettingsWindow(this.ClusterPlotViewModel.ClusterViewerSettings));

            this.Features    = new ObservableCollection <UMCLightViewModel>();
            this.MsMsSpectra = new ObservableCollection <MSSpectra>();

            this.ClusterPlotViewModel = new ClusterPlotViewModel(clusters);

            this.ShowChargeStateDistributionCommand = new RelayCommand(this.ShowChargeStateDistributionImpl);
            this.ShowDatasetHistogramCommand        = new RelayCommand(this.ShowDatasetHistogramImpl);

            this.layoutUpdated    = false;
            this.originalSettings = new ClusterViewerSettings();

            // Set up standard layout path
            var assemblyPath = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);

            if (!string.IsNullOrEmpty(assemblyPath))
            {
                this.standardLayoutFilePath = Path.Combine(assemblyPath, StandardLayoutFileName);
            }

            // Listen for changes in selected cluster in ClusterViewModel.
            Messenger.Default.Register <PropertyChangedMessage <UMCClusterLight> >(
                this,
                args =>
            {
                if (args.Sender == this.ClusterPlotViewModel && !this.ClusterPlotViewModel.SelectedCluster.Equals(this.SelectedMatch))
                {
                    this.SelectedMatch = this.Matches.FirstOrDefault(match => match.Cluster == this.ClusterPlotViewModel.SelectedCluster);
                }
            });

            // Listen for changes in selected cluster internally.
            Messenger.Default.Register <PropertyChangedMessage <ClusterMatch> >(
                this,
                arg =>
            {
                if (arg.Sender == this)
                {
                    this.throttler.Run(() => this.MatchSelected(arg));
                }
            });

            // When the selected MSFeature changes, update MS/MS spectra
            Messenger.Default.Register <PropertyChangedMessage <MSFeatureLight> >(
                this,
                arg =>
            {
                if (arg.Sender == this.XicPlotViewModel && arg.NewValue != null)
                {
                    this.MsMsSpectra.Clear();
                    foreach (var msmsSpectrum in arg.NewValue.MSnSpectra)
                    {
                        this.MsMsSpectra.Add(msmsSpectrum);
                    }

                    var first = this.MsMsSpectra.FirstOrDefault();
                    if (first != null)
                    {
                        this.SelectedMsMsSpectra = first;
                    }
                }
            });

            // Load layout.
            this.layoutFilePath = "layout.xml";
            this.LoadLayoutFile();

            if (this.Matches.Count > 0)
            {
                this.SelectedMatch = this.Matches[0];
            }
        }
 public IWooCommerceProductsService CreateProductsService(WooCommerceConfig config, Throttler throttler)
 {
     return(new WooCommerceProductsService(config, throttler));
 }
Пример #14
0
        public void ThrottledMetthodThrows()
        {
            // arrange
            throttled = new Throttler<int>(list => { throw new Exception("ERROR"); }, 100, TimeSpan.FromMilliseconds(100))
            {
                OnError = (ex, list) => waiter.Set()
            };

            throttled.Call(new int());

            // assert 1
            Assert.IsTrue(waiter.WaitOne(2000));
        }
Пример #15
0
        public void ThrottledMetthodIsNotCalledOnEmptyQueue()
        {
            // arrange
            throttled = new Throttler<int>(Reseter, 100, TimeSpan.FromMinutes(5));

            // test
            throttled.Flush();

            // assert
            Assert.IsFalse(waiter.WaitOne(2000));
        }
Пример #16
0
        public void ThrottledMetthodIsNotCalled()
        {
            // arrange
            throttled = new Throttler<int>(Reseter, 100, TimeSpan.FromMinutes(5));

            // test
            throttled.Call(new int());
            throttled.Call(new List<int>(5));

            // assert
            Assert.IsFalse(waiter.WaitOne(2000));
        }
Пример #17
0
 public FastAuthController(TParams config, IAccountManager manager, ILogger <SecureAuthController> logger, Throttler throttler, IHttpContextAccessor accessor, Settings settings)
 {
     _manager   = manager;
     _logger    = logger;
     _throttler = throttler;
     _accessor  = accessor;
     _config    = config;
     _settings  = settings;
 }
Пример #18
0
        public async Task <SuperHSShipment> CreateShipment(SuperHSShipment superShipment, DecodedToken decodedToken)
        {
            ShipmentItem firstShipmentItem = superShipment.ShipmentItems.First();
            string       supplierOrderID   = firstShipmentItem.OrderID;
            string       buyerOrderID      = supplierOrderID.Split("-").First();
            string       buyerID           = "";

            // in the platform, in order to make sure the order has the proper Order.Status, you must
            // create a shipment without a DateShipped and then patch the DateShipped after
            DateTimeOffset?dateShipped = superShipment.Shipment.DateShipped;

            superShipment.Shipment.DateShipped = null;

            await PatchLineItemStatuses(supplierOrderID, superShipment, OrderDirection.Incoming, decodedToken);

            if (decodedToken.CommerceRole != CommerceRole.Seller)
            {
                buyerID = await GetBuyerIDForSupplierOrder(firstShipmentItem.OrderID);
            }
            else
            {
                buyerID = superShipment.Shipment.xp.BuyerID;
            }
            superShipment.Shipment.BuyerID = buyerID;

            HSShipment ocShipment = await _oc.Shipments.CreateAsync <HSShipment>(superShipment.Shipment, accessToken : decodedToken.AccessToken);

            //  platform issue. Cant save new xp values onto shipment line item. Update order line item to have this value.
            var shipmentItemsWithComment = superShipment.ShipmentItems.Where(s => s.xp?.Comment != null);
            await Throttler.RunAsync(shipmentItemsWithComment, 100, 5, (shipmentItem) =>
            {
                dynamic comments                  = new ExpandoObject();
                var commentsByShipment            = comments as IDictionary <string, object>;
                commentsByShipment[ocShipment.ID] = shipmentItem.xp?.Comment;
                return(_oc.LineItems.PatchAsync(OrderDirection.Incoming, buyerOrderID, shipmentItem.LineItemID,
                                                new PartialLineItem()
                {
                    xp = new
                    {
                        Comments = commentsByShipment
                    }
                }));
            });

            IList <ShipmentItem> shipmentItemResponses = await Throttler.RunAsync(
                superShipment.ShipmentItems,
                100,
                5,
                (shipmentItem) => _oc.Shipments.SaveItemAsync(ocShipment.ID, shipmentItem, accessToken: decodedToken.AccessToken));

            HSShipment ocShipmentWithDateShipped = await _oc.Shipments.PatchAsync <HSShipment>(ocShipment.ID, new PartialShipment()
            {
                DateShipped = dateShipped
            }, accessToken : decodedToken.AccessToken);

            return(new SuperHSShipment()
            {
                Shipment = ocShipmentWithDateShipped,
                ShipmentItems = shipmentItemResponses.ToList()
            });
        }
Пример #19
0
        private void CheckTwoFactorAuthentication(string username, LoginRequest request)
        {
            bool isTwoFactorReq = !string.IsNullOrEmpty(request.TwoFactorGuid) || request.TwoFactorCode != null;

            if (isTwoFactorReq)
            {
                Check.NotNullOrEmpty(request.TwoFactorGuid, "twoFactorGuid");
                Check.NotNull(request.TwoFactorCode, "twoFactorCode");

                var key  = "TwoFactorAuth:" + request.TwoFactorGuid;
                var data = DistributedCache.Get <TwoFactorData>(key);
                if (data == null || data.Username == null || data.Username != username)
                {
                    throw new ValidationError("Can't validate credentials. Please try login again!");
                }

                data.RetryCount++;
                if (data.RetryCount > 3)
                {
                    DistributedCache.Set <TwoFactorData>(key, null);
                    throw new ValidationError("Can't validate credentials. Please try login again!");
                }
                else
                {
                    DistributedCache.Set(key, data);
                }

                if (data.TwoFactorCode != request.TwoFactorCode)
                {
                    throw new ValidationError("Validation code is invalid. Please check and try again.");
                }

                // login success. clear to not let same two factor guid/two factor code two be reused later
                DistributedCache.Set <TwoFactorData>(key, null);

                return;
            }

            var user = Dependency.Resolve <IUserRetrieveService>().ByUsername(username) as UserDefinition;

            if (user != null &&
                ((user.TwoFactorAuth == Administration.TwoFactorAuthType.SMS &&
                  user.MobilePhoneVerified &&
                  UserRepository.IsValidPhone(user.MobilePhoneNumber)) ||
                 (user.TwoFactorAuth == Administration.TwoFactorAuthType.Email)))
            {
                var env = Config.Get <EnvironmentSettings>();

                // you may disable two factor auth when <compilation debug="true" /> in web.config, by uncommenting lines below
                // if (HttpContext.IsDebuggingEnabled)
                //    return;

                var md5  = new MD5CryptoServiceProvider().ComputeHash(Encoding.UTF8.GetBytes(request.Password ?? ""));
                var data = new TwoFactorData
                {
                    RetryCount    = 0,
                    Username      = username,
                    TwoFactorCode = new Random().Next(9000) + 1000
                };

                // this is to prevent users from sending too many SMS in a certain time interval
                var throttler = new Throttler("TwoFactorAuthThrottle:" + username, TimeSpan.FromMinutes(5), 10);
                if (!throttler.Check())
                {
                    throw new ValidationError(
                              "Can't proceed with two factor authentication. You are over your validation limit!");
                }

                var twoFactorGuid = Guid.NewGuid().ToString("N");

                string authenticationMessage;
                if (user.TwoFactorAuth == Administration.TwoFactorAuthType.SMS)
                {
                    var mobile = user.MobilePhoneNumber.Trim();
                    Dependency.Resolve <Administration.ISMSService>().Send(
                        phoneNumber: mobile,
                        text: "Please use code " + data.TwoFactorCode + " for Allocation login.",
                        reason: "Sent by Allocation system for two factor authenication by SMS (" + user.Username +
                        ")");

                    // mask mobile number
                    mobile = mobile.Substring(0, 2) + new string('*', mobile.Length - 4) +
                             mobile.Substring(mobile.Length - 2, 2);
                    authenticationMessage = "Please enter code sent to your mobile phone with number " + mobile +
                                            " in <span class='counter'>{0}</span> seconds." +
                                            ((Dependency.Resolve <Administration.ISMSService>() is Administration
                                              .FakeSMSService)
                                                ? " (You can find a text file under App_Data/SMS directory, as you haven't configured SMS service yet)"
                                                : "");
                }
                else
                {
                    EmailHelper.Send(
                        address: user.Email,
                        subject: "Your two-factor authentication code for Allocation login",
                        body: "Please use code " + data.TwoFactorCode + " for Allocation login.");
                    authenticationMessage = "Please enter code sent to your e-mail adress in {0} seconds." +
                                            " (If you didn't configure an SMTP server, you can find e-mails under App_Data/Mail directory";
                }

                DistributedCache.Set("TwoFactorAuth:" + twoFactorGuid, data, TimeSpan.FromMinutes(2));
                throw new ValidationError("TwoFactorAuthenticationRequired",
                                          authenticationMessage + "|" + twoFactorGuid, "Two factor authentication is required!");
            }
        }
Пример #20
0
        private async Task HandleLineItemStatusChangeNotification(VerifiedUserType setterUserType, HSOrder buyerOrder, List <string> supplierIDsRelatedToChange, List <HSLineItem> lineItemsChanged, LineItemStatusChanges lineItemStatusChanges)
        {
            try
            {
                var suppliers = await Throttler.RunAsync(supplierIDsRelatedToChange, 100, 5, supplierID => _oc.Suppliers.GetAsync <HSSupplier>(supplierID));

                // currently the only place supplier name is used is when there should be lineitems from only one supplier included on the change, so we can just take the first supplier
                var statusChangeTextDictionary = LineItemStatusConstants.GetStatusChangeEmailText(suppliers.First().Name);

                foreach (KeyValuePair <VerifiedUserType, EmailDisplayText> entry in statusChangeTextDictionary[lineItemStatusChanges.Status])
                {
                    var userType  = entry.Key;
                    var emailText = entry.Value;

                    var firstName = "";
                    var lastName  = "";
                    var email     = "";

                    if (userType == VerifiedUserType.buyer)
                    {
                        firstName = buyerOrder.FromUser.FirstName;
                        lastName  = buyerOrder.FromUser.LastName;
                        email     = buyerOrder.FromUser.Email;
                        await _sendgridService.SendLineItemStatusChangeEmail(buyerOrder, lineItemStatusChanges, lineItemsChanged.ToList(), firstName, lastName, email, emailText);
                    }
                    else if (userType == VerifiedUserType.admin)
                    {
                        // Loop over seller users, pull out THEIR boolean, as well as the List<string> of AddtlRcpts
                        var sellerUsers = await _oc.AdminUsers.ListAsync <HSSellerUser>();

                        var tos = new List <EmailAddress>();
                        foreach (var seller in sellerUsers.Items)
                        {
                            if (seller?.xp?.OrderEmails ?? false)
                            {
                                tos.Add(new EmailAddress(seller.Email));
                            }
                            ;
                            if (seller?.xp?.AddtlRcpts?.Any() ?? false)
                            {
                                foreach (var rcpt in seller.xp.AddtlRcpts)
                                {
                                    tos.Add(new EmailAddress(rcpt));
                                }
                                ;
                            }
                            ;
                        }
                        ;
                        var shouldNotify = !(LineItemStatusConstants.LineItemStatusChangesDontNotifySetter.Contains(lineItemStatusChanges.Status) && setterUserType == VerifiedUserType.admin);
                        if (shouldNotify)
                        {
                            await _sendgridService.SendLineItemStatusChangeEmailMultipleRcpts(buyerOrder, lineItemStatusChanges, lineItemsChanged.ToList(), tos, emailText);
                        }
                    }
                    else
                    {
                        var shouldNotify = !(LineItemStatusConstants.LineItemStatusChangesDontNotifySetter.Contains(lineItemStatusChanges.Status) && setterUserType == VerifiedUserType.supplier);
                        if (shouldNotify)
                        {
                            await Throttler.RunAsync(suppliers, 100, 5, async supplier =>
                            {
                                if (supplier?.xp?.NotificationRcpts?.Any() ?? false)
                                {
                                    var tos = new List <EmailAddress>();
                                    foreach (var rcpt in supplier.xp.NotificationRcpts)
                                    {
                                        tos.Add(new EmailAddress(rcpt));
                                    }
                                    ;
                                    await _sendgridService.SendLineItemStatusChangeEmailMultipleRcpts(buyerOrder, lineItemStatusChanges, lineItemsChanged.ToList(), tos, emailText);
                                }
                            });
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                // track in app insights
                // to find go to Transaction Search > Event Type = Event > Filter by any of these custom properties or event name "Email.LineItemEmailFailed"
                var customProperties = new Dictionary <string, string>
                {
                    { "Message", "Attempt to email line item changes failed" },
                    { "BuyerOrderID", buyerOrder.ID },
                    { "BuyerID", buyerOrder.FromCompanyID },
                    { "UserEmail", buyerOrder.FromUser.Email },
                    { "UserType", setterUserType.ToString() },
                    { "ErrorResponse", JsonConvert.SerializeObject(ex.Message, Newtonsoft.Json.Formatting.Indented) }
                };
                _telemetry.TrackEvent("Email.LineItemEmailFailed", customProperties);
                return;
            }
        }
    public void Awake()
    {
		bulletsLeft = BurstCount;
        playerCamera = GetComponentInChildren<CameraScript>();
        weaponIndicator = Camera.main.GetComponent<WeaponIndicatorScript>();
        targets = weaponIndicator.Targets;
        playerScript = GetComponent<PlayerScript>();

        GunRecoilThrotter = new Throttler<float>();
        GunRecoilThrotter.MinimumTimeBetweenItems = 0.09f;
        GunRecoilSpring = new ScalarSpring(0f);
        GunRecoilSpring.Strength = 2000f;
        GunRecoilSpring.Damping = 0.00000000001f;
        ReloaderSpring = new ScalarSpring(0f);
        ReloaderSpring.Strength = 200f;
        ReloaderSpring.Damping = 0.00000001f;
        ReloaderDelayer = new Delayer<float>();
        ReloaderDelayer.DelayTime = 0.25f;
    }
 public IWooCommerceSystemStatusService CreateSystemStatusService(WooCommerceConfig config, Throttler throttler)
 {
     return(new WooCommerceSystemStatusService(config, throttler));
 }
Пример #23
0
        protected override async Task WorkAction()
        {
            // check if pruning is turned off
            var mode = this.Mode;

            if (mode == PruningMode.None)
            {
                return;
            }

            // navigate from the current pruned chain towards the current processed chain
            foreach (var pathElement in this.prunedChain.ToImmutable().NavigateTowards(() => this.coreDaemon.CurrentChain))
            {
                // cooperative loop
                if (!this.IsStarted)
                {
                    break;
                }

                // get candidate block to be pruned
                var direction     = pathElement.Item1;
                var chainedHeader = pathElement.Item2;

                // get the current processed chain
                var processedChain = this.coreDaemon.CurrentChain;

                // determine maximum safe pruning height, based on a buffer distance from the processed chain height
                var blocksPerDay = 144;
                //TODO there should also be a buffer between when blocks are pruned, and when the pruning information
                //TODO to perform that operation is removed (tx index, spent txes)
                var pruneBuffer = blocksPerDay * 7;
                var maxHeight   = processedChain.Height - pruneBuffer;
                //TODO
                maxHeight = Math.Min(maxHeight, this.PrunableHeight);

                // check if this block is safe to prune
                if (chainedHeader.Height > maxHeight)
                {
                    break;
                }

                if (direction > 0)
                {
                    // prune the block, except genesis block
                    if (chainedHeader.Height > 0)
                    {
                        await this.PruneBlock(mode, processedChain, chainedHeader);
                    }

                    // track pruned block
                    this.prunedChain.AddBlock(chainedHeader);
                }
                else if (direction < 0)
                {
                    // pruning should not roll back, the buffer is in place to prevent this on orphans
                    throw new InvalidOperationException();
                }
                else
                {
                    throw new InvalidOperationException();
                }

                // pause chain state processing when pruning lags too far behind
                var isLagging = maxHeight - chainedHeader.Height > 100;
                if (isLagging)
                {
                    Throttler.IfElapsed(TimeSpan.FromSeconds(5), () =>
                    {
                        logger.Info("Pruning is lagging.");
                        lagLogged = true;
                    });

                    //TODO better way to block chain state worker when pruning is behind
                    if (this.chainStateWorker?.IsStarted ?? false)
                    {
                        this.chainStateWorker.Stop(TimeSpan.Zero);
                    }
                }
                else
                {
                    //TODO better way to block chain state worker when pruning is behind
                    if (!(this.chainStateWorker?.IsStarted ?? true))
                    {
                        this.chainStateWorker.NotifyAndStart();
                        if (lagLogged)
                        {
                            logger.Info("Pruning is caught up.");
                            lagLogged = false;
                        }
                    }
                }

                // log pruning stats periodically
                Throttler.IfElapsed(TimeSpan.FromSeconds(15), () =>
                {
                    logger.Info(string.Join(Environment.NewLine,
                                            $"Pruned from block {lastLogHeight:N0} to {chainedHeader.Height:N0}:",
                                            $"- avg tx rate:    {txRateMeasure.GetAverage(),8:N0}/s",
                                            $"- per block stats:",
                                            $"- tx count:       {txCountMeasure.GetAverage(),8:N0}",
                                            $"- prune blocks:   {pruneBlockTxesDurationMeasure.GetAverage().TotalMilliseconds,12:N3}ms",
                                            $"- prune index:    {pruneTxIndexDurationMeasure.GetAverage().TotalMilliseconds,12:N3}ms",
                                            $"- prune spent:    {pruneSpentTxesDurationMeasure.GetAverage().TotalMilliseconds,12:N3}ms",
                                            $"- TOTAL:          {totalDurationMeasure.GetAverage().TotalMilliseconds,12:N3}ms"
                                            ));

                    lastLogHeight = chainedHeader.Height + 1;
                });
            }

            // ensure chain state processing is resumed
            if (!(this.chainStateWorker?.IsStarted ?? true))
            {
                this.chainStateWorker.NotifyAndStart();
            }
        }
 public OrderItemsService( IMarketplaceWebServiceOrders client, ListOrderItemsRequest request, Throttler throttler )
 {
     this._client = client;
     this._request = request;
     this._throttler = throttler;
 }
        public async Task <JObject> CreateAsync(WorkItem wi)
        {
            var obj = wi.Current.ToObject <SuperHSProduct>();

            try
            {
                obj.ID = wi.RecordId;
                var ps = await _oc.PriceSchedules.CreateAsync(obj.PriceSchedule, wi.Token);

                var product = await _oc.Products.CreateAsync <HSProduct>(obj.Product, wi.Token);

                await _oc.Products.SaveAssignmentAsync(new ProductAssignment()
                {
                    ProductID       = product.ID,
                    PriceScheduleID = ps.ID
                }, wi.Token);

                var specs = await Throttler.RunAsync(obj.Specs, 250, 20, spec => _oc.Specs.CreateAsync(spec, wi.Token));

                await Throttler.RunAsync(specs, 250, 20, spec => _oc.Specs.SaveProductAssignmentAsync(
                                             new SpecProductAssignment()
                {
                    ProductID = product.ID,
                    SpecID    = spec.ID
                }, wi.Token));

                var list    = obj.Specs.SelectMany(spec => spec.Options).ToList();
                var options = Throttler.RunAsync(list, 100, 40, option => _oc.Specs.CreateOptionAsync(option.xp.SpecID, option, wi.Token));
                // attempt to generate variants if option is set
                if (specs.Any(s => s.DefinesVariant))
                {
                    await _oc.Products.GenerateVariantsAsync <HSProduct>(product.ID, true, wi.Token);
                }
                var variants = await _oc.Products.ListVariantsAsync <HSVariant>(product.ID, null, null, null, 1, 100, null, wi.Token);

                //var _images = GetProductImages(id, user);
                //var _attachments = GetProductAttachments(id, user);
                return(JObject.FromObject(new SuperHSProduct
                {
                    Product = product,
                    PriceSchedule = ps,
                    Specs = specs,
                    Variants = variants.Items
                }));
            }
            catch (OrderCloudException exId) when(IdExists(exId))
            {
                // handle 409 errors by refreshing cache
                await _log.Save(new OrchestrationLog(wi)
                {
                    ErrorType        = OrchestrationErrorType.CreateExistsError,
                    Message          = exId.Message,
                    Level            = LogLevel.Error,
                    OrderCloudErrors = exId.Errors
                });

                return(await GetAsync(wi));
            }
            catch (OrderCloudException ex)
            {
                await _log.Save(new OrchestrationLog(wi)
                {
                    ErrorType        = OrchestrationErrorType.CreateGeneralError,
                    Message          = ex.Message,
                    Level            = LogLevel.Error,
                    OrderCloudErrors = ex.Errors
                });

                throw new Exception(OrchestrationErrorType.CreateGeneralError.ToString(), ex);
            }
            catch (Exception e)
            {
                await _log.Save(new OrchestrationLog(wi)
                {
                    ErrorType = OrchestrationErrorType.CreateGeneralError,
                    Message   = e.Message,
                    Level     = LogLevel.Error
                });

                throw new Exception(OrchestrationErrorType.CreateGeneralError.ToString(), e);
            }
        }
        public async Task <List <TemplateProductFlat> > PostTemplateFlatProducts([FromBody] List <TemplateProductFlat> obj)
        {
            var result = await Throttler.RunAsync(obj, 100, 100, p => _command.SaveToQueue(p, this.VerifiedUserContext, this.VerifiedUserContext.SupplierID));

            return(result.ToList());
        }
Пример #27
0
        /// <summary>
        /// Initializes a new instance of the <see cref="XicPlotViewModel"/> class.
        /// </summary>
        public XicPlotViewModel(ScanSummaryProviderCache rawProvider)
        {
            this.rawProvider          = rawProvider;
            this.plotBuilderthrottler = new Throttler(TimeSpan.FromMilliseconds(100));
            this.yaxisScaleThrottler  = new Throttler(TimeSpan.FromMilliseconds(20));
            this.ChargeStates         = new ObservableCollection <ChargeStateViewModel>();
            this.XicPlotModel         = new PlotModel
            {
                Title = "Extracted Ion Chromatograms",
                ////RenderingDecorator = rc => new XkcdRenderingDecorator(rc)
            };

            this.AutoScaleYAxis = true;

            this.xaxis = new LinearAxis
            {
                Title           = "NET",
                Position        = AxisPosition.Bottom,
                AbsoluteMinimum = 0,
                AbsoluteMaximum = 1.0,
                Minimum         = 0,
            };

            this.yaxis = new LinearAxis
            {
                Title           = "Abundance",
                Position        = AxisPosition.Left,
                AbsoluteMinimum = 0,
                Minimum         = 0,
                StringFormat    = "0.###E0",
                IsPanEnabled    = false,
                IsZoomEnabled   = false,
            };

            this.xaxis.AxisChanged += (o, e) =>
            {
                if (this.AutoScaleYAxis)
                {
                    this.ScaleYAxis();
                }
            };

            this.SavePlotCommand = new RelayCommand(this.SavePlot);

            this.XicPlotModel.Axes.Add(this.xaxis);
            this.XicPlotModel.Axes.Add(this.yaxis);

            this.XicPlotModel.MouseDown += this.XicPlotMouseDown;

            Messenger.Default.Register <PropertyChangedMessage <bool> >(this, this.ChargeStateSelectionChanged);
            Messenger.Default.Register <PropertyChangedMessage <bool> >(this, this.FeatureSelectionChanged);
            Messenger.Default.Register <PropertyChangedMessage <MSFeatureLight> >(this, arg =>
            {
                this.SetMsFeatureAnnotation();
                this.XicPlotModel.InvalidatePlot(true);
            });

            Messenger.Default.Register <PropertyChangedMessage <bool> >(this, arg =>
            {
                if (arg.Sender == this && arg.PropertyName == "AutoScaleYAxis")
                {
                    this.yaxis.IsZoomEnabled = !arg.NewValue;
                    this.yaxis.IsPanEnabled  = !arg.NewValue;
                    if (arg.NewValue)
                    {
                        this.xaxis.Reset();
                        this.yaxis.Reset();
                        this.ScaleYAxis();
                        this.XicPlotModel.InvalidatePlot(false);
                    }
                }
            });
        }
Пример #28
0
        public async Task ProcessSampleProducts(string filename, ILogger logger)
        {
            logger.LogInformation("Processing Sample Products");
            List <PriceSchedule>         prices                 = new List <PriceSchedule>();
            List <Product>               products               = new List <Product>();
            List <Spec>                  specs                  = new List <Spec>();
            List <SpecOption>            specOptions            = new List <SpecOption>();
            List <SpecProductAssignment> specProductAssignments = new List <SpecProductAssignment>();
            List <VariantPlaceholder>    variantPlaceholders    = new List <VariantPlaceholder>();


            // Map Customer Provided Product Data to OrderCloud Headstart Classes
            var binDirectory  = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            var rootDirectory = Path.GetFullPath(Path.Combine(binDirectory, ".."));
            SampleProductList productsFromFile = JsonConvert.DeserializeObject <SampleProductList>(File.ReadAllText(rootDirectory + filename));

            foreach (SampleProduct product in productsFromFile.products)
            {
                // Build list of Price Schedules
                var priceSchedule = ProductMapping.MapOCPriceSchedule(product);
                prices.Add(priceSchedule);

                // Build list of Products
                var tempProduct = ProductMapping.MapOCProduct(product);
                products.Add(tempProduct);

                // Build Specs if more than 1 product in group
                if (product.options.Count > 0)
                {
                    foreach (SampleOption option in product.options)
                    {
                        var tempSpec = ProductMapping.MapOCProductSpec(option);
                        specs.Add(tempSpec);

                        foreach (string val in option.values)
                        {
                            var tempOption = ProductMapping.MapOCProductSpecOption(product.id, option.name, val);
                            specOptions.Add(tempOption);

                            // The sample data provided will generate a simple list of variants based solely on color options.
                            // Real world products will require more robust data mapping for variants if the need to modify them exists.
                            var tempVariant = ProductMapping.MapOCProductVariant(product, option, val);
                            variantPlaceholders.Add(tempVariant);
                        }

                        var tempSPA = ProductMapping.MapOCProductSpecAssignment(product.id, option.name);
                        specProductAssignments.Add(tempSPA);
                    }
                }
            }

            // Build PriceShcedule
            await Throttler.RunAsync(prices, 100, 20, price => BuildPriceScheduleOC(price, logger));

            // Build Product
            await Throttler.RunAsync(products, 100, 20, product => BuildProductOC(product, logger));

            if (specs.Count > 0)
            {
                // Build Specs
                await Throttler.RunAsync(specs, 100, 20, spec => BuildSpecOC(spec, logger));

                // Build Spec Options
                await Throttler.RunAsync(specOptions, 100, 20, specoption => BuildSpecOptionOC(specoption, logger));

                // Assign Specs to Product
                await Throttler.RunAsync(specProductAssignments, 100, 20, specprodassignment => BuildSpecProductAssignmentOC(specprodassignment, logger));

                // Generate Variants
                var variantGroups = variantPlaceholders.GroupBy(v => v.ProductID);
                foreach (IList <VariantPlaceholder> variantGroup in variantGroups)
                {
                    // Allow the system to generate variants based on selection specs
                    await GenerateOCVariants(variantGroup[0].ProductID, logger);

                    //Modify the generated specs to use custom variant id's
                    await Throttler.RunAsync(variantGroup, 500, 1, variant => UpdateProductVariantsOC(variant, logger));
                }
            }
            logger.LogInformation($"Process BrandwearProducts Complete.");
        }
Пример #29
0
 public void LogBlockchainProgress()
 {
     Throttler.IfElapsed(TimeSpan.FromSeconds(15), () =>
                         logger.Info(stats.ToString()));
 }
 public HotKeyAction(int id, Action action)
 {
     Id         = id;
     _action    = action;
     _throttler = new Throttler(0.04);
 }
Пример #31
0
 public async Task TryThrottleAsync_IsCancelled_Throw()
 {
     var throttler = new Throttler(() => DateTime.Now, 1);
     await Assert.ThrowsAsync <TaskCanceledException>(async() => await throttler.TryThrottleAsync(
                                                          ("x", 1), TimeSpan.FromDays(1), new CancellationToken(true)));
 }
        private bool ValidateFirstTimeUser(ref string username, string password)
        {
            var throttler = new Throttler("ValidateUser:"******"Error on directory first time authentication", ex, this.GetType());
                return(false);
            }

            try
            {
                string salt        = null;
                var    hash        = UserRepository.GenerateHash(password, ref salt);
                var    displayName = entry.FirstName + " " + entry.LastName;
                var    email       = entry.Email.TrimToNull() ?? (username + "@yourdefaultdomain.com");
                username = entry.Username.TrimToNull() ?? username;

                using (var connection = SqlConnections.NewFor <UserRow>())
                    using (var uow = new UnitOfWork(connection))
                    {
                        var userId = (int)connection.InsertAndGetID(new UserRow
                        {
                            Username            = username,
                            Source              = "ldap",
                            DisplayName         = displayName,
                            Email               = email,
                            PasswordHash        = hash,
                            PasswordSalt        = salt,
                            IsActive            = 1,
                            InsertDate          = DateTime.Now,
                            InsertUserId        = 1,
                            LastDirectoryUpdate = DateTime.Now
                        });

                        uow.Commit();

                        UserRetrieveService.RemoveCachedUser(userId, username);
                    }

                return(true);
            }
            catch (Exception ex)
            {
                Log.Error("Error while importing directory user", ex, this.GetType());
                return(false);
            }
        }
Пример #33
0
        public async Task <SuperHSProduct> Post(SuperHSProduct superProduct, DecodedToken decodedToken)
        {
            // Determine ID up front so price schedule ID can match
            superProduct.Product.ID = superProduct.Product.ID ?? CosmosInteropID.New();

            await ValidateVariantsAsync(superProduct, decodedToken.AccessToken);

            // Create Specs
            var defaultSpecOptions = new List <DefaultOptionSpecAssignment>();
            var specRequests       = await Throttler.RunAsync(superProduct.Specs, 100, 5, s =>
            {
                defaultSpecOptions.Add(new DefaultOptionSpecAssignment {
                    SpecID = s.ID, OptionID = s.DefaultOptionID
                });
                s.DefaultOptionID = null;
                return(_oc.Specs.SaveAsync <Spec>(s.ID, s, accessToken: decodedToken.AccessToken));
            });

            // Create Spec Options
            foreach (Spec spec in superProduct.Specs)
            {
                await Throttler.RunAsync(spec.Options, 100, 5, o => _oc.Specs.SaveOptionAsync(spec.ID, o.ID, o, accessToken: decodedToken.AccessToken));
            }
            // Patch Specs with requested DefaultOptionID
            await Throttler.RunAsync(defaultSpecOptions, 100, 10, a => _oc.Specs.PatchAsync(a.SpecID, new PartialSpec {
                DefaultOptionID = a.OptionID
            }, accessToken: decodedToken.AccessToken));

            // Create Price Schedule
            PriceSchedule _priceSchedule = null;

            //All products must have a price schedule for orders to be submitted.  The front end provides a default Price of $0 for quote products that don't have one.
            superProduct.PriceSchedule.ID = superProduct.Product.ID;
            try
            {
                _priceSchedule = await _oc.PriceSchedules.CreateAsync <PriceSchedule>(superProduct.PriceSchedule, decodedToken.AccessToken);
            }
            catch (OrderCloudException ex)
            {
                if (ex.HttpStatus == System.Net.HttpStatusCode.Conflict)
                {
                    throw new Exception($"Product SKU {superProduct.PriceSchedule.ID} already exists.  Please try a different SKU.");
                }
            }
            superProduct.Product.DefaultPriceScheduleID = _priceSchedule.ID;
            // Create Product
            if (decodedToken.CommerceRole == CommerceRole.Supplier)
            {
                var me = await _oc.Me.GetAsync(accessToken : decodedToken.AccessToken);

                var supplierName = await GetSupplierNameForXpFacet(me.Supplier.ID, decodedToken.AccessToken);

                superProduct.Product.xp.Facets.Add("supplier", new List <string>()
                {
                    supplierName
                });
            }
            var _product = await _oc.Products.CreateAsync <HSProduct>(superProduct.Product, decodedToken.AccessToken);

            // Make Spec Product Assignments
            await Throttler.RunAsync(superProduct.Specs, 100, 5, s => _oc.Specs.SaveProductAssignmentAsync(new SpecProductAssignment {
                ProductID = _product.ID, SpecID = s.ID
            }, accessToken: decodedToken.AccessToken));

            // Generate Variants
            await _oc.Products.GenerateVariantsAsync(_product.ID, accessToken : decodedToken.AccessToken);

            // Patch Variants with the User Specified ID(SKU) AND necessary display xp values
            await Throttler.RunAsync(superProduct.Variants, 100, 5, v =>
            {
                var oldVariantID = v.ID;
                v.ID             = v.xp.NewID ?? v.ID;
                v.Name           = v.xp.NewID ?? v.ID;

                if ((superProduct?.Product?.Inventory?.VariantLevelTracking) == true && v.Inventory == null)
                {
                    v.Inventory = new PartialVariantInventory {
                        QuantityAvailable = 0
                    };
                }
                if (superProduct.Product?.Inventory == null)
                {
                    //If Inventory doesn't exist on the product, don't patch variants with inventory either.
                    return(_oc.Products.PatchVariantAsync(_product.ID, oldVariantID, new PartialVariant {
                        ID = v.ID, Name = v.Name, xp = v.xp
                    }, accessToken: decodedToken.AccessToken));
                }
                else
                {
                    return(_oc.Products.PatchVariantAsync(_product.ID, oldVariantID, new PartialVariant {
                        ID = v.ID, Name = v.Name, xp = v.xp, Inventory = v.Inventory
                    }, accessToken: decodedToken.AccessToken));
                }
            });


            // List Variants
            var _variants = await _oc.Products.ListVariantsAsync <HSVariant>(_product.ID, accessToken : decodedToken.AccessToken);

            // List Product Specs
            var _specs = await _oc.Products.ListSpecsAsync <Spec>(_product.ID, accessToken : decodedToken.AccessToken);

            // Return the SuperProduct
            return(new SuperHSProduct
            {
                Product = _product,
                PriceSchedule = _priceSchedule,
                Specs = _specs.Items,
                Variants = _variants.Items,
            });
        }
Пример #34
0
    public void Awake() 
	{
        DontDestroyOnLoad(gameObject);

		warningSpheres = new List<GameObject>();

        controller = GetComponent<CharacterController>();
        characterAnimation = transform.Find("Animated Mesh Fixed").GetComponent<Animation>();
        characterAnimation.Play("idle");
	    textBubble = gameObject.FindChild("TextBubble");
        textBubble.GetComponent<Renderer>().material.color = new Color(1, 1, 1, 0);

	    characterAnimation["run"].speed = 1.25f;
        characterAnimation["backward"].speed = 1.75f;
        characterAnimation["strafeLeft"].speed = 1.5f;
        characterAnimation["strafeRight"].speed = 1.5f;

        foreach (var r in GetComponentsInChildren<Renderer>())
        {
            if (!r.material.HasProperty("_Color")) continue;
            if (r.gameObject.name == "TextBubble") continue;
            if (r.gameObject.name == "flag_flag001") continue;
            r.tag = "PlayerMaterial";
        }

        EnemiesTargetingUs = new EnemiesTargetingUs();
        EnemiesTargetingUs.OnStartedBeingLockedOnByEnemy += ReceiveStartedBeingLockedOnBy;
        EnemiesTargetingUs.OnStoppedBeingLockedOnByEnemy += ReceiveStoppedBeingLockedOnBy;

        OtherPlayerVisibilityLayerMask =
            (1 << LayerMask.NameToLayer("Player")) | (1 << LayerMask.NameToLayer("Default"));

        if (uLink.Network.isServer)
        {
            // Averaging slowly from this value, so start somewhere sensible
            LastNetworkFrameTakeTime = Relay.DesiredTimeBetweenNetworkSends;
            RecentWorstNetworkTakeTime = Relay.DesiredTimeBetweenNetworkSends;
        }
        FootstepThrottler = new Throttler<Action>
        {
            MinimumTimeBetweenItems = 0.17f
        };
	}
Пример #35
0
        public async Task <SuperHSProduct> Put(string id, SuperHSProduct superProduct, string token)
        {
            // Update the Product itself
            var _updatedProduct = await _oc.Products.SaveAsync <HSProduct>(superProduct.Product.ID, superProduct.Product, token);

            // Two spec lists to compare (requestSpecs and existingSpecs)
            IList <Spec> requestSpecs  = superProduct.Specs.ToList();
            IList <Spec> existingSpecs = (await _oc.Products.ListSpecsAsync(id, accessToken: token)).Items.ToList();
            // Two variant lists to compare (requestVariants and existingVariants)
            IList <HSVariant> requestVariants  = superProduct.Variants;
            IList <Variant>   existingVariants = (await _oc.Products.ListVariantsAsync(id, pageSize: 100, accessToken: token)).Items.ToList();
            // Calculate differences in specs - specs to add, and specs to delete
            var specsToAdd    = requestSpecs.Where(s => !existingSpecs.Any(s2 => s2.ID == s.ID)).ToList();
            var specsToDelete = existingSpecs.Where(s => !requestSpecs.Any(s2 => s2.ID == s.ID)).ToList();

            // Get spec options to add -- WAIT ON THESE, RUN PARALLEL THE ADD AND DELETE SPEC REQUESTS
            foreach (var rSpec in requestSpecs)
            {
                foreach (var eSpec in existingSpecs)
                {
                    if (rSpec.ID == eSpec.ID)
                    {
                        await Throttler.RunAsync(rSpec.Options.Where(rso => !eSpec.Options.Any(eso => eso.ID == rso.ID)), 100, 5, o => _oc.Specs.CreateOptionAsync(rSpec.ID, o, accessToken: token));

                        await Throttler.RunAsync(eSpec.Options.Where(eso => !rSpec.Options.Any(rso => rso.ID == eso.ID)), 100, 5, o => _oc.Specs.DeleteOptionAsync(rSpec.ID, o.ID, accessToken: token));
                    }
                }
                ;
            }
            ;
            // Create new specs and Delete removed specs
            var defaultSpecOptions = new List <DefaultOptionSpecAssignment>();
            await Throttler.RunAsync(specsToAdd, 100, 5, s =>
            {
                defaultSpecOptions.Add(new DefaultOptionSpecAssignment {
                    SpecID = s.ID, OptionID = s.DefaultOptionID
                });
                s.DefaultOptionID = null;
                return(_oc.Specs.SaveAsync <Spec>(s.ID, s, accessToken: token));
            });

            await Throttler.RunAsync(specsToDelete, 100, 5, s => _oc.Specs.DeleteAsync(s.ID, accessToken: token));

            // Add spec options for new specs
            foreach (var spec in specsToAdd)
            {
                await Throttler.RunAsync(spec.Options, 100, 5, o => _oc.Specs.CreateOptionAsync(spec.ID, o, accessToken: token));
            }
            // Patch Specs with requested DefaultOptionID
            await Throttler.RunAsync(defaultSpecOptions, 100, 10, a => _oc.Specs.PatchAsync(a.SpecID, new PartialSpec {
                DefaultOptionID = a.OptionID
            }, accessToken: token));

            // Make assignments for the new specs
            await Throttler.RunAsync(specsToAdd, 100, 5, s => _oc.Specs.SaveProductAssignmentAsync(new SpecProductAssignment {
                ProductID = id, SpecID = s.ID
            }, accessToken: token));

            HandleSpecOptionChanges(requestSpecs, existingSpecs, token);
            // Check if Variants differ
            var  variantsAdded    = requestVariants.Any(v => !existingVariants.Any(v2 => v2.ID == v.ID));
            var  variantsRemoved  = existingVariants.Any(v => !requestVariants.Any(v2 => v2.ID == v.ID));
            bool hasVariantChange = false;

            foreach (Variant variant in requestVariants)
            {
                ValidateRequestVariant(variant);
                var currVariant = existingVariants.Where(v => v.ID == variant.ID);
                if (currVariant == null || currVariant.Count() < 1)
                {
                    continue;
                }
                hasVariantChange = HasVariantChange(variant, currVariant.First());
                if (hasVariantChange)
                {
                    break;
                }
            }
            // IF variants differ, then re-generate variants and re-patch IDs to match the user input.
            if (variantsAdded || variantsRemoved || hasVariantChange || requestVariants.Any(v => v.xp.NewID != null))
            {
                //validate variant names before continuing saving.
                await ValidateVariantsAsync(superProduct, token);

                // Re-generate Variants
                await _oc.Products.GenerateVariantsAsync(id, overwriteExisting : true, accessToken : token);

                // Patch NEW variants with the User Specified ID (Name,ID), and correct xp values (SKU)
                await Throttler.RunAsync(superProduct.Variants, 100, 5, v =>
                {
                    v.ID   = v.xp.NewID ?? v.ID;
                    v.Name = v.xp.NewID ?? v.ID;
                    if ((superProduct?.Product?.Inventory?.VariantLevelTracking) == true && v.Inventory == null)
                    {
                        v.Inventory = new PartialVariantInventory {
                            QuantityAvailable = 0
                        };
                    }
                    if (superProduct.Product?.Inventory == null)
                    {
                        //If Inventory doesn't exist on the product, don't patch variants with inventory either.
                        return(_oc.Products.PatchVariantAsync(id, $"{superProduct.Product.ID}-{v.xp.SpecCombo}", new PartialVariant {
                            ID = v.ID, Name = v.Name, xp = v.xp, Active = v.Active
                        }, accessToken: token));
                    }
                    else
                    {
                        return(_oc.Products.PatchVariantAsync(id, $"{superProduct.Product.ID}-{v.xp.SpecCombo}", new PartialVariant {
                            ID = v.ID, Name = v.Name, xp = v.xp, Active = v.Active, Inventory = v.Inventory
                        }, accessToken: token));
                    }
                });
            }
            ;
            // If applicable, update OR create the Product PriceSchedule
            var tasks = new List <Task>();
            Task <PriceSchedule> _priceScheduleReq = null;

            if (superProduct.PriceSchedule != null)
            {
                _priceScheduleReq = UpdateRelatedPriceSchedules(superProduct.PriceSchedule, token);
                tasks.Add(_priceScheduleReq);
            }
            // List Variants
            var _variantsReq = _oc.Products.ListVariantsAsync <HSVariant>(id, pageSize: 100, accessToken: token);

            tasks.Add(_variantsReq);
            // List Product Specs
            var _specsReq = _oc.Products.ListSpecsAsync <Spec>(id, accessToken: token);

            tasks.Add(_specsReq);

            await Task.WhenAll(tasks);

            return(new SuperHSProduct
            {
                Product = _updatedProduct,
                PriceSchedule = _priceScheduleReq?.Result,
                Specs = _specsReq?.Result?.Items,
                Variants = _variantsReq?.Result?.Items,
            });
        }
Пример #36
0
 public void Init()
 {
     _throttler = new Throttler( 5, 2 );
     _callCounter = 0;
     _callCounterFunc = () => _callCounter++;
 }
Пример #37
0
        public async Task <HSSupplier> Create(HSSupplier supplier, VerifiedUserContext user, bool isSeedingEnvironment = false)
        {
            var token = isSeedingEnvironment ? user.AccessToken : null;

            // Create Supplier
            supplier.ID = "{supplierIncrementor}";
            var ocSupplier = await _oc.Suppliers.CreateAsync(supplier, token);

            supplier.ID = ocSupplier.ID;
            var ocSupplierID = ocSupplier.ID;

            // Create Integrations Supplier User
            var supplierUser = await _oc.SupplierUsers.CreateAsync(ocSupplierID, new User()
            {
                Active    = true,
                Email     = user.Email,
                FirstName = "Integration",
                LastName  = "Developer",
                Password  = "******", // _settings.OrderCloudSettings.DefaultPassword,
                Username  = $"dev_{ocSupplierID}"
            }, token);

            await CreateUserTypeUserGroupsAndSecurityProfileAssignments(supplierUser, token, ocSupplierID);

            // Create API Client for new supplier
            var apiClient = await _oc.ApiClients.CreateAsync(new ApiClient()
            {
                AppName = $"Integration Client {ocSupplier.Name}",
                Active  = true,
                DefaultContextUserName = supplierUser.Username,
                ClientSecret           = _settings.OrderCloudSettings.MiddlewareClientSecret,
                AccessTokenDuration    = 600,
                RefreshTokenDuration   = 43200,
                AllowAnyBuyer          = false,
                AllowAnySupplier       = false,
                AllowSeller            = false,
                IsAnonBuyer            = false,
            }, token);


            // not adding api client ID on supplier Create because that approach would require creating the API client first
            // but creating supplier first is preferable in case there are error in the request
            ocSupplier = await _oc.Suppliers.PatchAsync(ocSupplier.ID, new PartialSupplier()
            {
                xp = new
                {
                    ApiClientID = apiClient.ID
                }
            }, token);

            // Assign Supplier API Client to new supplier
            await _oc.ApiClients.SaveAssignmentAsync(new ApiClientAssignment()
            {
                ApiClientID = apiClient.ID,
                SupplierID  = ocSupplierID
            }, token);

            // list message senders
            var msList = await _oc.MessageSenders.ListAsync(accessToken : token);

            // create message sender assignment
            var assignmentList = msList.Items.Select(ms =>
            {
                return(new MessageSenderAssignment
                {
                    MessageSenderID = ms.ID,
                    SupplierID = ocSupplierID
                });
            });
            await Throttler.RunAsync(assignmentList, 100, 5, a => _oc.MessageSenders.SaveAssignmentAsync(a, token));

            return(supplier);
        }