/// <summary> /// Gets the details of an existing subscription. /// </summary> /// <param name="subscriptionId"> /// The subscription id. /// </param> /// <returns> /// The <see cref="Subscription"/>. /// </returns> public Subscription GetSubscription(string subscriptionId) { var cacheKey = MakeSubscriptionCacheKey(subscriptionId); if (Exists(subscriptionId)) { var subscription = (Subscription)RuntimeCache.GetCacheItem(cacheKey); if (subscription != null) { return(subscription); } var attempt = TryGetApiResult(() => BraintreeGateway.Subscription.Find(subscriptionId)); if (!attempt.Success) { return(null); } subscription = attempt.Result; return((Subscription)RuntimeCache.GetCacheItem(cacheKey, () => subscription)); } return(null); }
/// <summary> /// Quotes all available ship methods /// </summary> /// <param name="tryGetCached"> /// If set true the strategy will try to get a quote from cache /// </param> /// <returns> /// A collection of <see cref="IShipmentRateQuote"/> /// </returns> public override IEnumerable <IShipmentRateQuote> GetShipmentRateQuotes(bool tryGetCached = true) { var quotes = new List <IShipmentRateQuote>(); foreach (var gwShipMethod in ShippingGatewayMethods) { var rateQuote = tryGetCached ? TryGetCachedShipmentRateQuote(Shipment, gwShipMethod) : default(ShipmentRateQuote); if (rateQuote == null) { // REFACTOR-v3 this would only need happen if an attempt was to get cached, then not, then cached again // without any changes. RuntimeCache.ClearCacheItem(GetShipmentRateQuoteCacheKey(Shipment, gwShipMethod)); //// http://issues.merchello.com/youtrack/issue/M-458 //// Clones the shipment so that with each iteration so that we can have the same shipment //// with different ship methods //// REFACTOR-v3 clone should be inherent on ICloneableEntity var attempt = gwShipMethod.QuoteShipment(Shipment.Clone()); if (attempt.Success) { rateQuote = attempt.Result; RuntimeCache.GetCacheItem(GetShipmentRateQuoteCacheKey(Shipment, gwShipMethod), () => rateQuote, TimeSpan.FromMinutes(5)); } } if (rateQuote != null) { quotes.Add(rateQuote); } } return(quotes); }
/// <summary> /// Updates a payment method /// </summary> /// <param name="token">The payment method token</param> /// <param name="request"> /// The request. /// </param> /// <returns> /// The <see cref="Attempt"/>. /// </returns> public Attempt <PaymentMethod> Update(string token, PaymentMethodRequest request) { Mandate.ParameterNotNull(request, "request"); Updating.RaiseEvent(new SaveEventArgs <PaymentMethodRequest>(request), this); var attempt = TryGetApiResult(() => BraintreeGateway.PaymentMethod.Update(token, request)); if (!attempt.Success) { return(Attempt <PaymentMethod> .Fail(attempt.Exception)); } var result = attempt.Result; if (result.IsSuccess()) { var cacheKey = MakePaymentMethodCacheKey(token); RuntimeCache.ClearCacheItem(cacheKey); Updated.RaiseEvent(new SaveEventArgs <PaymentMethod>(result.Target), this); return(Attempt <PaymentMethod> .Succeed((PaymentMethod)RuntimeCache.GetCacheItem(cacheKey, () => result.Target))); } var error = new BraintreeApiException(result.Errors, result.Message); LogHelper.Error <BraintreePaymentMethodApiService>("Failed to update payment method", error); return(Attempt <PaymentMethod> .Fail(error)); }
public IEnumerable <IContent> GetByPublishedVersion(IQuery <IContent> query) { // we WANT to return contents in top-down order, ie parents should come before children // ideal would be pure xml "document order" which can be achieved with: // ORDER BY substring(path, 1, len(path) - charindex(',', reverse(path))), sortOrder // but that's probably an overkill - sorting by level,sortOrder should be enough var sqlClause = GetBaseQuery(false); var translator = new SqlTranslator <IContent>(sqlClause, query); var sql = translator.Translate() .Where <DocumentDto>(x => x.Published) .OrderBy <NodeDto>(x => x.Level, SqlSyntax) .OrderBy <NodeDto>(x => x.SortOrder, SqlSyntax); //NOTE: This doesn't allow properties to be part of the query var dtos = Database.Fetch <DocumentDto, ContentVersionDto, ContentDto, NodeDto, DocumentPublishedReadOnlyDto>(sql); foreach (var dto in dtos) { //Check in the cache first. If it exists there AND it is published // then we can use that entity. Otherwise if it is not published (which can be the case // because we only store the 'latest' entries in the cache which might not be the published // version) var fromCache = RuntimeCache.GetCacheItem <IContent>(GetCacheIdKey <IContent>(dto.NodeId)); //var fromCache = TryGetFromCache(dto.NodeId); if (fromCache != null && fromCache.Published) { yield return(fromCache); } else { yield return(CreateContentFromDto(dto, dto.VersionId, sql)); } } }
/// <summary> /// Gets a <see cref="PaymentMethod"/>. /// </summary> /// <param name="token"> /// The token. /// </param> /// <returns> /// The <see cref="PaymentMethod"/>. /// </returns> public PaymentMethod GetPaymentMethod(string token) { var cacheKey = MakePaymentMethodCacheKey(token); if (Exists(token)) { var paymentMethod = (PaymentMethod)RuntimeCache.GetCacheItem(cacheKey); if (paymentMethod != null) { return(paymentMethod); } // this following should never happen as the Exists should cache it but its a good fallback var attempt = TryGetApiResult(() => BraintreeGateway.PaymentMethod.Find(token)); if (attempt.Success) { RuntimeCache.GetCacheItem(cacheKey, () => attempt.Result); } return(attempt.Success ? attempt.Result : null); } return(null); }
/// <summary> /// Quotes all available shipmethods /// </summary> /// <returns>A collection of <see cref="IShipmentRateQuote"/></returns> public override IEnumerable <IShipmentRateQuote> GetShipmentRateQuotes() { var quotes = new List <IShipmentRateQuote>(); foreach (var gwShipMethod in ShippingGatewayMethods) { var rateQuote = TryGetCachedShipmentRateQuote(Shipment, gwShipMethod); if (rateQuote == null) { var attempt = gwShipMethod.QuoteShipment(Shipment); if (attempt.Success) { rateQuote = attempt.Result; RuntimeCache.GetCacheItem(GetShipmentRateQuoteCacheKey(Shipment, gwShipMethod), () => rateQuote); } } if (rateQuote != null) { quotes.Add(rateQuote); } } return(quotes); }
/// <summary> /// Creates a Braintree <see cref="Customer"/> from a Merchello <see cref="ICustomer"/> /// </summary> /// <param name="customer"> /// The customer. /// </param> /// <param name="paymentMethodNonce"> /// The "nonce-from-the-client" /// </param> /// <param name="billingAddress"> /// The billing address /// </param> /// <param name="shippingAddress"> /// The shipping Address. /// </param> /// <returns> /// The <see cref="Attempt{Customer}"/>. /// </returns> public Attempt <Customer> Create(ICustomer customer, string paymentMethodNonce = "", IAddress billingAddress = null, IAddress shippingAddress = null) { if (Exists(customer)) { return(Attempt.Succeed(GetBraintreeCustomer(customer))); } var request = RequestFactory.CreateCustomerRequest(customer, paymentMethodNonce, billingAddress); Creating.RaiseEvent(new Core.Events.NewEventArgs <CustomerRequest>(request), this); // attempt the API call var attempt = TryGetApiResult(() => BraintreeGateway.Customer.Create(request)); if (!attempt.Success) { return(Attempt <Customer> .Fail(attempt.Exception)); } var result = attempt.Result; if (result.IsSuccess()) { Created.RaiseEvent(new Core.Events.NewEventArgs <Customer>(result.Target), this); return(Attempt.Succeed((Customer)RuntimeCache.GetCacheItem(MakeCustomerCacheKey(customer), () => result.Target))); } var error = new BraintreeApiException(result.Errors); LogHelper.Error <BraintreeCustomerApiService>("Braintree API Customer Create return a failure", error); return(Attempt <Customer> .Fail(error)); }
/// <summary> /// Gets <see cref="IEntityFilterGroup"/> by it's key. /// </summary> /// <param name="key"> /// The key. /// </param> /// <returns> /// The <see cref="IEntityFilterGroup"/>. /// </returns> /// <remarks> /// TODO this is pretty brittle since it assumes the collection will be intended to be used as the special filter group. /// However, it merely builds a filter group using whatever collection and it's children - so Service should definitely /// have this as an internal method until we can refactor /// </remarks> public IEntityFilterGroup GetEntityFilterGroup(Guid key) { var cacheKey = Cache.CacheKeys.GetEntityCacheKey <IEntityFilterGroup>(key); var cached = (IEntityFilterGroup)RuntimeCache.GetCacheItem(cacheKey); if (cached != null) { return(cached); } var collection = Get(key); if (collection == null) { return(null); } var query = Querying.Query <IEntityCollection> .Builder.Where(x => x.ParentKey == key); var children = GetByQuery(query); var filterGroup = new EntityFilterGroup(collection); foreach (var child in children) { filterGroup.Filters.Add(child); } return((IEntityFilterGroup)RuntimeCache.GetCacheItem(cacheKey, () => filterGroup)); }
/// <summary> /// Gets an entity by the passed in Id /// </summary> /// <param name="key"> /// The key. /// </param> /// <returns> /// The entity retrieved /// </returns> public TEntity Get(Guid key) { if (IsCachedRepository) { var fromCache = TryGetFromCache(key); if (fromCache.Success) { return(fromCache.Result); } } var entity = PerformGet(key); if (entity != null) { RuntimeCache.GetCacheItem(GetCacheKey(key), () => entity); } if (entity != null) { entity.ResetDirtyProperties(); } return(entity); }
/// <summary> /// Quotes all available ship methods /// </summary> /// <param name="tryGetCached"> /// If set true the strategy will try to get a quote from cache /// </param> /// <returns> /// A collection of <see cref="IShipmentRateQuote"/> /// </returns> public override IEnumerable <IShipmentRateQuote> GetShipmentRateQuotes(bool tryGetCached = true) { var quotes = new List <IShipmentRateQuote>(); foreach (var gwShipMethod in ShippingGatewayMethods) { var rateQuote = tryGetCached ? TryGetCachedShipmentRateQuote(Shipment, gwShipMethod) : default(ShipmentRateQuote); if (rateQuote == null) { RuntimeCache.ClearCacheItem(GetShipmentRateQuoteCacheKey(Shipment, gwShipMethod)); //// http://issues.merchello.com/youtrack/issue/M-458 //// Clones the shipment so that with each iteration so that we can have the same shipment //// with different ship methods var attempt = gwShipMethod.QuoteShipment(Shipment.Clone()); if (attempt.Success) { rateQuote = attempt.Result; RuntimeCache.GetCacheItem(GetShipmentRateQuoteCacheKey(Shipment, gwShipMethod), () => rateQuote); } } if (rateQuote != null) { quotes.Add(rateQuote); } } return(quotes); }
/// <summary> /// The try get from cache. /// </summary> /// <param name="key"> /// The key. /// </param> /// <returns> /// The <see cref="Attempt"/>. /// </returns> protected Attempt <TEntity> TryGetFromCache(Guid key) { var cacheKey = GetCacheKey(key); var retEntity = RuntimeCache.GetCacheItem(cacheKey); return(retEntity != null ? Attempt <TEntity> .Succeed((TEntity)retEntity) : Attempt <TEntity> .Fail()); }
/// <summary> /// Gets all entities of type TEntity or a list according to the passed in Ids /// </summary> /// <param name="keys">The keys of the entities to be returned</param> /// <returns>A collection of entities</returns> public IEnumerable <TEntity> GetAll(params Guid[] keys) { if (keys.Any()) { var entities = new List <TEntity>(); foreach (var key in keys) { var entity = RuntimeCache.GetCacheItem(GetCacheKey(key)); if (entity != null) { entities.Add((TEntity)entity); } } if (entities.Count().Equals(keys.Count()) && entities.Any(x => x == null) == false) { return(entities); } } else { // fix http://issues.merchello.com/youtrack/issue/M-159 // Since IProduct and IProductVaraint both start with IProduct which was causing the cache conflict var allEntities = RuntimeCache.GetCacheItemsByKeySearch(typeof(TEntity).Name + ".").ToArray(); ////_cache.GetAllByType(typeof(TEntity)); if (allEntities.Any()) { var query = Querying.Query <TEntity> .Builder.Where(x => x.Key != Guid.Empty); var totalCount = PerformCount(query); if (allEntities.Count() == totalCount) { return(allEntities.Select(x => (TEntity)x)); } } } var entityCollection = PerformGetAll(keys).ToArray(); foreach (var entity in entityCollection) { if (entity != null) { RuntimeCache.GetCacheItem(GetCacheKey(entity.Key), () => entity); } } return(entityCollection); }
/// <summary> /// Adds a credit card to an existing customer. /// </summary> /// <param name="customer"> /// The customer. /// </param> /// <param name="paymentMethodNonce"> /// The payment method nonce. /// </param> /// <param name="token"> /// The token. /// </param> /// <param name="billingAddress"> /// The billing address. /// </param> /// <param name="isDefault"> /// A value indicating whether or not this payment method should become the default payment method. /// </param> /// <returns> /// The <see cref="Attempt{PaymentMethod}"/> indicating whether the payment method creation was successful. /// </returns> public Attempt <PaymentMethod> Create(ICustomer customer, string paymentMethodNonce, string token, IAddress billingAddress = null, bool isDefault = true) { //// Asserts the customer exists or creates one in BrainTree if it does not exist var btc = _braintreeCustomerApiService.GetBraintreeCustomer(customer); var request = RequestFactory.CreatePaymentMethodRequest(customer, paymentMethodNonce); if (!string.IsNullOrEmpty(token)) { request.Token = token; } if (billingAddress != null) { request.BillingAddress = RequestFactory.CreatePaymentMethodAddressRequest(billingAddress); } Creating.RaiseEvent(new Core.Events.NewEventArgs <PaymentMethodRequest>(request), this); var attempt = TryGetApiResult(() => BraintreeGateway.PaymentMethod.Create(request)); if (!attempt.Success) { return(Attempt <PaymentMethod> .Fail(attempt.Exception)); } var result = attempt.Result; if (result.IsSuccess()) { var cacheKey = MakePaymentMethodCacheKey(token); RuntimeCache.ClearCacheItem(cacheKey); var customerCacheKey = MakeCustomerCacheKey(customer); RuntimeCache.ClearCacheItem(customerCacheKey); Created.RaiseEvent(new Core.Events.NewEventArgs <PaymentMethod>(result.Target), this); return(Attempt <PaymentMethod> .Succeed((PaymentMethod)RuntimeCache.GetCacheItem(cacheKey, () => result.Target))); } var error = new BraintreeApiException(result.Errors, result.Message); LogHelper.Error <BraintreeCustomerApiService>("Failed to add a credit card to a customer", error); return(Attempt <PaymentMethod> .Fail(error)); }
/// <summary> /// Unit of work method that tells the repository to persist the updated entity /// </summary> /// <param name="entity">The entity to be updated</param> public virtual void PersistUpdatedItem(IEntity entity) { try { PersistUpdatedItem((TEntity)entity); RuntimeCache.GetCacheItem(GetCacheKey(entity.Key), () => entity); } catch (Exception ex) { LogHelper.Error(GetType(), "An error occurred trying to update an exiting entity", ex); ////if an exception is thrown we need to remove the entry from cache, this is ONLY a work around because of the way //// that we cache entities: http://issues.umbraco.org/issue/U4-4259 RuntimeCache.ClearCacheItem(GetCacheKey(entity.Key)); throw; } }
/// <summary> /// Gets an entity by it's id. /// </summary> /// <param name="id"> /// The id of the entity. /// </param> /// <param name="lazy"> /// Lazy properties. /// </param> /// <returns> /// The <see cref="TEntity"/>. /// </returns> public virtual TEntity Get(Guid id, bool lazy = true) { var cacheKey = GetCacheKey(id); if (lazy) { return(PerformGet(id)); } var result = RuntimeCache.GetCacheItem(cacheKey); if (result != null) { return((TEntity)result); } // cache for 5 minutes return((TEntity)RuntimeCache.GetCacheItem(cacheKey, () => PerformGet(id, false), TimeSpan.FromMinutes(5))); }
/// <summary> /// Gets the Braintree <see cref="Customer"/> corresponding to the Merchello <see cref="ICustomer"/> /// </summary> /// <param name="customer"> /// The customer. /// </param> /// <param name="createOnNotFound"> /// True or false indicating whether or not the customer should be automatically created if not found /// </param> /// <returns> /// The <see cref="Customer"/>. /// </returns> public Customer GetBraintreeCustomer(ICustomer customer, bool createOnNotFound = true) { Mandate.ParameterNotNull(customer, "customer"); if (Exists(customer)) { var cacheKey = MakeCustomerCacheKey(customer); return((Customer)RuntimeCache.GetCacheItem(cacheKey, () => BraintreeGateway.Customer.Find(customer.Key.ToString()))); } if (!createOnNotFound) { return(null); } var attempt = this.Create(customer); return(attempt.Success ? attempt.Result : null); }
/// <inheritdoc /> public IEnumerable <ICountry> GetAllCountries() { const string CacheKey = "ALLCOUNTRIES"; return((IEnumerable <ICountry>)RuntimeCache.GetCacheItem( CacheKey, () => { //// TODO - this needs to be refactored: //// Possible to return multiple countries for a given 2 digit code //// Culture info does not account for every country. return CultureInfo.GetCultures(CultureTypes.SpecificCultures) .Select(culture => new RegionInfo(culture.Name)) .Select(ri => new Country { Code = ri.TwoLetterISORegionName, Name = ri.EnglishName }) .DistinctBy(c => c.Code) .OrderBy(c => c.Name) .ToArray(); })); }
/// <summary> /// Returns true or false indicating whether the customer exists in Braintree /// </summary> /// <param name="customer"> /// The customer. /// </param> /// <returns> /// The <see cref="bool"/>. /// </returns> public bool Exists(ICustomer customer) { var cacheKey = MakeCustomerCacheKey(customer); var braintreeCustomer = RuntimeCache.GetCacheItem(cacheKey); if (braintreeCustomer == null) { var attempt = TryGetApiResult(() => BraintreeGateway.Customer.Find(customer.Key.ToString())); if (!attempt.Success) { return(false); } braintreeCustomer = attempt.Result; RuntimeCache.GetCacheItem(cacheKey, () => braintreeCustomer); } return(braintreeCustomer != null); }
/// <summary> /// Returns true or false indicating whether the customer exists in Braintree. /// </summary> /// <param name="token"> /// The token reference. /// </param> /// <returns> /// A value indicating whether or not the payment method exists. /// </returns> public bool Exists(string token) { var cacheKey = MakePaymentMethodCacheKey(token); var paymentMethod = (PaymentMethod)RuntimeCache.GetCacheItem(cacheKey); if (paymentMethod == null) { var attempt = TryGetApiResult(() => BraintreeGateway.PaymentMethod.Find(token)); if (!attempt.Success) { return(false); } paymentMethod = attempt.Result; RuntimeCache.GetCacheItem(cacheKey, () => paymentMethod); return(true); } return(true); }
/// <summary> /// Determines if a subscription exists /// </summary> /// <param name="subscriptionId"> /// The subscription id. /// </param> /// <returns> /// A value indicating whether or not a subscription exists. /// </returns> public bool Exists(string subscriptionId) { var cacheKey = MakeSubscriptionCacheKey(subscriptionId); var subscription = (Subscription)RuntimeCache.GetCacheItem(cacheKey); if (subscription != null) { return(true); } var attempt = TryGetApiResult(() => BraintreeGateway.Subscription.Find(subscriptionId)); if (attempt.Success) { subscription = attempt.Result; RuntimeCache.GetCacheItem(cacheKey, () => subscription); return(true); } RuntimeCache.ClearCacheItem(cacheKey); return(false); }
/// <summary> /// The update. /// </summary> /// <param name="customer"> /// The customer. /// </param> /// <param name="paymentMethodNonce">The "nonce-from-the-client"</param> /// <param name="billingAddress">The customer billing address</param> /// <param name="shippinggAddress">The shipping address</param> /// <returns> /// The <see cref="Customer"/>. /// </returns> public Attempt <Customer> Update(ICustomer customer, string paymentMethodNonce = "", IAddress billingAddress = null, IAddress shippinggAddress = null) { if (!this.Exists(customer)) { return(Attempt <Customer> .Fail(new NullReferenceException("Could not finde matching Braintree customer."))); } var request = RequestFactory.CreateCustomerRequest(customer, paymentMethodNonce, billingAddress, true); Updating.RaiseEvent(new SaveEventArgs <CustomerRequest>(request), this); // attempt the API call var attempt = TryGetApiResult(() => BraintreeGateway.Customer.Update(customer.Key.ToString(), request)); if (!attempt.Success) { return(Attempt <Customer> .Fail(attempt.Exception)); } var result = attempt.Result; if (result.IsSuccess()) { var cacheKey = MakeCustomerCacheKey(customer); RuntimeCache.ClearCacheItem(cacheKey); Updated.RaiseEvent(new SaveEventArgs <Customer>(result.Target), this); return(Attempt <Customer> .Succeed((Customer)RuntimeCache.GetCacheItem(cacheKey, () => result.Target))); } var error = new BraintreeApiException(result.Errors); LogHelper.Error <BraintreeCustomerApiService>("Braintree API Customer Create return a failure", error); return(Attempt <Customer> .Fail(error)); }
public TT GetCacheItem <TT>(string cacheKey) { return(RuntimeCache.GetCacheItem <TT>(cacheKey)); }
public TT GetCacheItem <TT>(string cacheKey, TimeSpan timeout, Func <TT> getCacheItem) { return(RuntimeCache.GetCacheItem <TT>(cacheKey, getCacheItem, timeout)); }
public TT GetCacheItem <TT>(string cacheKey, Func <TT> getCacheItem) { return(RuntimeCache.GetCacheItem <TT>(cacheKey, getCacheItem)); }
public TT GetCacheItem <TT>(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, TimeSpan timeout, Func <TT> getCacheItem) { return(RuntimeCache.GetCacheItem <TT>(cacheKey, getCacheItem, timeout, false, priority, refreshAction)); }