/// <summary>
 /// This method deletes an entity by its reference.
 /// </summary>
 /// <param name="refKey">The reference key, i.e. email etc.</param>
 /// <param name="refValue">The reference value.</param>
 /// <param name="settings">The persistence request settings.</param>
 /// <returns>Returns a response holder that indicates the status of the request and the entity or key and version id where appropriate.</returns>
 public virtual async Task <RepositoryHolder <K, Tuple <K, string> > > DeleteByRef(string refKey, string refValue, RepositorySettings settings = null)
 {
     return(await TransmitInternal(EntityActions.DeleteByRef, new RepositoryHolder <K, Tuple <K, string> > {
         KeyReference = new Tuple <string, string>(refKey, refValue), Settings = settings
     }, principal : DefaultPrincipal));
 }
        /// <summary>
        /// This method resolves an entity by its reference
        /// </summary>
        /// <param name="refKey">The reference key, i.e. email etc.</param>
        /// <param name="refValue">The reference value.</param>
        /// <param name="settings">The persistence request settings.</param>
        /// <returns>Returns a response holder that indicates the status of the request and the entity or key and version id where appropriate.</returns>
        public virtual async Task <RepositoryHolder <K, Tuple <K, string> > > VersionByRef(string refKey, string refValue, RepositorySettings settings = null)
        {
            if ((settings?.UseCache ?? true) && mCacheManager.IsActive)
            {
                var result = await mCacheManager.VersionRead(new Tuple <string, string>(refKey, refValue));

                if (result.IsSuccess)
                {
                    return(new RepositoryHolder <K, Tuple <K, string> >(result.Entity.Item1, new Tuple <string, string>(result.Id, result.VersionId), responseCode: 200, entity: result.Entity)
                    {
                        IsCached = true
                    });
                }
            }

            return(await TransmitInternal(EntityActions.VersionByRef, new RepositoryHolder <K, Tuple <K, string> > {
                KeyReference = new Tuple <string, string>(refKey, refValue), Settings = settings
            }, principal : DefaultPrincipal));
        }
        /// <summary>
        /// This method reads and entity by the reference key/value pair.
        /// </summary>
        /// <param name="refKey">The reference key, i.e. email etc.</param>
        /// <param name="refValue">The reference value.</param>
        /// <param name="settings">The persistence request settings.</param>
        /// <returns>Returns a response holder that indicates the status of the request and the entity or key and version id where appropriate.</returns>
        public virtual async Task <RepositoryHolder <K, E> > ReadByRef(string refKey, string refValue, RepositorySettings settings = null)
        {
            if ((settings?.UseCache ?? true) && mCacheManager.IsActive)
            {
                // Do a version read initially to check it is there and get the key (not returned in a read by ref)
                var resultVersion = await mCacheManager.VersionRead(new Tuple <string, string>(refKey, refValue));

                if (resultVersion.IsSuccess)
                {
                    var resultRead = await mCacheManager.Read(new Tuple <string, string>(refKey, refValue));

                    if (resultRead.IsSuccess)
                    {
                        return new RepositoryHolder <K, E>(resultVersion.Entity.Item1, new Tuple <string, string>(resultVersion.Id, resultVersion.VersionId), responseCode: 200, entity: resultRead.Entity)
                               {
                                   IsCached = true
                               }
                    }
                    ;
                }
            }

            return(await TransmitInternal(EntityActions.ReadByRef, new RepositoryHolder <K, E> {
                KeyReference = new Tuple <string, string>(refKey, refValue), Settings = settings
            }, principal : DefaultPrincipal));
        }
 /// <summary>
 /// This method deletes an entity by its key.
 /// </summary>
 /// <param name="key">The entity key.</param>
 /// <param name="settings">The persistence request settings.</param>
 /// <returns>Returns a response holder that indicates the status of the request and the entity or key and version id where appropriate.</returns>
 public virtual async Task <RepositoryHolder <K, Tuple <K, string> > > Delete(K key, RepositorySettings settings = null)
 {
     return(await TransmitInternal(EntityActions.Delete, new RepositoryHolder <K, Tuple <K, string> > {
         Key = key, Settings = settings
     }, principal : DefaultPrincipal));
 }
Exemple #5
0
        /// <summary>
        /// This method reads an entity based on the key passed.
        /// </summary>
        /// <param name="key">The key request.</param>
        /// <param name="options">These are the repository options which define the request type..</param>
        /// <returns>This is the holder containing the response and the entity where necessary.</returns>
        public virtual async Task <RepositoryHolder <SearchRequest, SearchResponse> > Search(SearchRequest key, RepositorySettings options = null)
        {
            var uri = mUriMapper.MakeUri(new HttpMethod("Search"));

            throw new NotImplementedException();
            //using (var content = GetContent(entity))
            //{
            //    return await CallClient<K, E>(uri, options, content: content, deserializer: DeserializeEntity,
            //        mapper: (rs, holder) => ExtractHeaders(rs, holder, mKeyMapper));
            //}
        }
Exemple #6
0
        /// <summary>
        /// This method calls the client using HTTP and returns the response along with the entity in the response if supplied.
        /// </summary>
        /// <typeparam name="KT">The key type.</typeparam>
        /// <typeparam name="ET">The entity type.</typeparam>
        /// <param name="uri">The request uri.</param>
        /// <param name="options">The repository settings passed from the caller.</param>
        /// <param name="content">The HttpContent to send to the API.</param>
        /// <param name="adjust">Any message adjustment.</param>
        /// <param name="mapper">Any response adjustment before returning to the caller.</param>
        /// <param name="deserializer">Deserialize the response content into the entity</param>
        /// <returns></returns>
        protected virtual async Task <RepositoryHolder <KT, ET> > CallClient <KT, ET>(
            KeyValuePair <HttpMethod, Uri> uri
            , RepositorySettings options
            , HttpContent content = null
            , Action <HttpRequestMessage> adjust = null
            , Action <HttpResponseMessage, RepositoryHolder <KT, ET> > mapper = null
            , Action <HttpResponseMessage, byte[], RepositoryHolder <KT, ET> > deserializer = null)
        {
            var response = new RepositoryHolder <KT, ET>();

            try
            {
                HttpRequestMessage httpRq = Request(uri.Key, uri.Value);

                RequestHeadersSet(httpRq);

                RequestHeadersSetTransport(httpRq);

                RequestHeadersPreferSet(httpRq, options?.Prefer);

                RequestHeadersAuth(httpRq);

                adjust?.Invoke(httpRq);

                if (content != null)
                {
                    httpRq.Content = content;
                }

                var client = new HttpClient();

                // Specify request body
                var httpRs = await client.SendAsync(httpRq);

                ResponseHeadersAuth(httpRq, httpRs);

                //OK, set the response content if set
                if (httpRs.Content != null && httpRs.Content.Headers.ContentLength > 0)
                {
                    byte[] httpRsContent = await httpRs.Content.ReadAsByteArrayAsync();

                    if (httpRs.IsSuccessStatusCode)
                    {
                        deserializer?.Invoke(httpRs, httpRsContent, response);
                    }
                    else
                    {
                        // So that we can see error messages such as schema validation fail
                        response.ResponseMessage = Encoding.UTF8.GetString(httpRsContent);
                    }
                }

                //Get any outgoing trace headers and set them in to the response.
                IEnumerable <string> trace;
                if (httpRs.Headers.TryGetValues(ApimConstants.AzureTraceHeaderLocation, out trace))
                {
                    response.Settings.Prefer.Add(ApimConstants.AzureTraceHeaderLocation, trace.First());
                }

                response.ResponseCode = (int)httpRs.StatusCode;

                mapper?.Invoke(httpRs, response);
            }
            catch (Exception ex)
            {
                response.ResponseMessage = FormatExceptionChain(ex);
                response.ResponseCode    = 503;
            }

            return(response);
        }
Exemple #7
0
        /// <summary>
        /// This method deletes an entity.
        /// </summary>
        /// <param name="key">The entity unique key.</param>
        /// <param name="options">These are the repository options which define the request type..</param>
        /// <returns>This is the holder containing the response and the entity where necessary.</returns>
        public virtual async Task <RepositoryHolder <K, Tuple <K, string> > > Delete(K key, RepositorySettings options = null)
        {
            var uri = GetUri(HttpMethod.Delete, key);

            return(await CallClient <K, Tuple <K, string> >(uri, options
                                                            , mapper : (rs, holder) => ExtractHeaders(rs, holder)));
        }
Exemple #8
0
 /// <summary>
 /// This method reads an entity based on the key passed.
 /// </summary>
 /// <param name="key">The key request.</param>
 /// <param name="options">These are the repository options which define the request type..</param>
 /// <returns>This is the holder containing the response and the entity where necessary.</returns>
 public virtual async Task <RepositoryHolder <SearchRequest, SearchResponse> > Search(SearchRequest key, RepositorySettings options = null)
 {
     throw new NotSupportedException();
 }
Exemple #9
0
        /// <summary>
        /// This method logs entities to the event source. This method will try indefinitely
        /// as we do not want the Event Source to fail.
        /// </summary>
        /// <typeparam Name="KT">The key type.</typeparam>
        /// <param name="actionType"></param>
        /// <param name="originatorKey"></param>
        /// <param name="key"></param>
        /// <param name="entity"></param>
        /// <param name="settings"></param>
        protected async virtual Task LogEventSource <KT>(string actionType, string originatorKey, KT key, E entity, RepositorySettings settings)
        {
            try
            {
                var data = new EventSourceEntry <KT, E>
                {
                    EntityType       = typeof(E).Name,
                    EventType        = actionType,
                    Entity           = entity,
                    EntityKey        = key,
                    EntitySource     = settings?.Source,
                    EntitySourceId   = settings?.SourceId,
                    EntitySourceName = settings?.SourceName
                };

                if (settings != null)
                {
                    data.BatchId          = settings.BatchId;
                    data.CorrelationId    = settings.CorrelationId;
                    data.EntityVersionOld = settings.VersionId;

                    data.EntityVersion = settings.VersionId;
                }

                await EventSource.Write(originatorKey, data, sync : true);
            }
            catch (Exception ex)
            {
                Logger.LogException($"Exception thrown for log to event source on {typeof (E).Name}-{actionType}-{originatorKey}", ex);
            }
        }
Exemple #10
0
        /// <summary>
        /// This method reads a reference based on its reference key and value.
        /// </summary>
        /// <param name="refKey">The key type.</param>
        /// <param name="refValue">The key value.</param>
        /// <param name="options">These are the repository options which define the request type..</param>
        /// <returns>This is the holder containing the response and the entity where necessary.</returns>
        public virtual async Task <RepositoryHolder <K, E> > ReadByRef(string refKey, string refValue, RepositorySettings options = null)
        {
            var uri = GetUri(HttpMethod.Get, refKey, refValue);

            return(await CallClient <K, E>(uri, options
                                           , deserializer : EntityDeserialize
                                           , mapper : (rs, holder) => ExtractHeaders(rs, holder)));
        }
        /// <summary>
        /// This method resolves an entity by its key.
        /// </summary>
        /// <param name="key">The entity key.</param>
        /// <param name="settings">The persistence request settings.</param>
        /// <returns>Returns a response holder that indicates the status of the request and the entity or key and version id where appropriate.</returns>
        public virtual async Task <RepositoryHolder <K, Tuple <K, string> > > Version(K key, RepositorySettings settings = null)
        {
            ValidateServiceStarted();

            if ((settings?.UseCache ?? true) && mCacheManager.IsActive)
            {
                var result = await mCacheManager.VersionRead(key);

                if (result.IsSuccess)
                {
                    return(new RepositoryHolder <K, Tuple <K, string> >(result.Entity.Item1, new Tuple <string, string>(result.Id, result.VersionId), responseCode: 200, entity: result.Entity)
                    {
                        IsCached = true
                    });
                }
            }

            return(await TransmitInternal(EntityActions.Version, new RepositoryHolder <K, Tuple <K, string> > {
                Key = key, Settings = settings
            }, principal : DefaultPrincipal));
        }
Exemple #12
0
 /// <summary>
 /// This method updates an entity.
 /// </summary>
 /// <param name="entity">The entity to update.</param>
 /// <param name="settings">The persistence settings.</param>
 /// <returns>Returns a response holder that indicates the status of the request and the entity or key and version id where appropriate.</returns>
 public virtual async Task <RepositoryHolder <K, E> > Update(E entity, RepositorySettings settings = null)
 {
     return(await TransmitInternal(EntityActions.Update, new RepositoryHolder <K, E> {
         Entity = entity, Settings = settings
     }));
 }
Exemple #13
0
        /// <summary>
        /// This method calls the client using HTTP and returns the response along with the entity in the response if supplied.
        /// </summary>
        /// <typeparam name="KT">The key type.</typeparam>
        /// <typeparam name="ET">The entity type.</typeparam>
        /// <param name="uri">The request uri.</param>
        /// <param name="options">The repository settings passed from the caller.</param>
        /// <param name="content">The HttpContent to send to the API.</param>
        /// <param name="adjust">Any message adjustment.</param>
        /// <param name="mapper">Any response adjustment before returning to the caller.</param>
        /// <param name="deserializer">Deserialize the response content into the entity</param>
        /// <returns></returns>
        protected virtual async Task <RepositoryHolder <KT, ET> > CallClient <KT, ET>(
            KeyValuePair <HttpMethod, Uri> uri
            , RepositorySettings options
            , HttpContent content = null
            , Action <HttpRequestMessage> adjust = null
            , Action <HttpResponseMessage, RepositoryHolder <KT, ET> > mapper = null
            , Action <HttpResponseMessage, byte[], RepositoryHolder <KT, ET> > deserializer = null)
        {
            var rs = new RepositoryHolder <KT, ET>();

            try
            {
                HttpRequestMessage rq = Request(uri.Key, uri.Value);

                adjust?.Invoke(rq);

                if (content != null)
                {
                    rq.Content = content;
                }

                if (options?.Prefer != null && options.Prefer.Count > 0)
                {
                    rq.Headers.Add("Prefer", options.Prefer.Select((k) => string.Format("{0}={1}", k.Key, k.Value)));
                }

                var client = new HttpClient();

                // Specify request body
                var response = await client.SendAsync(rq);

                if (response.Content != null && response.Content.Headers.ContentLength > 0)
                {
                    byte[] rsContent = await response.Content.ReadAsByteArrayAsync();

                    if (response.IsSuccessStatusCode)
                    {
                        deserializer?.Invoke(response, rsContent, rs);
                    }
                    else
                    {
                        // So that we can see error messages such as schema validation fail
                        rs.ResponseMessage = Encoding.UTF8.GetString(rsContent);
                    }
                }

                //Get any outgoing trace headers and set them in to the response.
                IEnumerable <string> trace;
                if (response.Headers.TryGetValues(ApimConstants.AzureTraceHeaderLocation, out trace))
                {
                    rs.Settings.Prefer.Add(ApimConstants.AzureTraceHeaderLocation, trace.First());
                }

                rs.ResponseCode = (int)response.StatusCode;

                mapper?.Invoke(response, rs);
            }
            catch (Exception ex)
            {
                rs.ResponseMessage = FormatExceptionChain(ex);
                rs.ResponseCode    = 503;
            }

            return(rs);
        }
        /// <summary>
        /// This method issues a search request.
        /// </summary>
        /// <param name="rq">The search request.</param>
        /// <param name="settings">The persistence request settings.</param>
        /// <returns>The search response.</returns>
        public virtual async Task <RepositoryHolder <SearchRequest, SearchResponse> > Search(SearchRequest rq, RepositorySettings settings = null)
        {
            //if ((settings?.UseCache ?? true) && mCacheManager.IsActive)
            //{
            //    var result = await mCacheManager.VersionRead(new Tuple<string, string>(refKey, refValue));
            //    if (result.IsSuccess)
            //    {
            //        return new RepositoryHolder<K, Tuple<K, string>>(result.Entity.Item1, new Tuple<string, string>(result.Id, result.VersionId), responseCode: 200, entity: result.Entity) { IsCached = true };
            //    }
            //}

            return(await TransmitInternal(EntityActions.Search, new RepositoryHolder <SearchRequest, SearchResponse> {
                Key = rq, Settings = settings
            }, principal : DefaultPrincipal));
        }
Exemple #15
0
        /// <summary>
        /// Thi method resolves the entity id and version based on the reference parameters.
        /// </summary>
        /// <param name="refKey">The key type.</param>
        /// <param name="refValue">The key value.</param>
        /// <param name="options">These are the repository options which define the request type..</param>
        /// <returns>This is the holder containing the response and the entity where necessary.</returns>
        public virtual async Task <RepositoryHolder <K, Tuple <K, string> > > VersionByRef(string refKey, string refValue, RepositorySettings options = null)
        {
            var uri = GetUri(HttpMethod.Head, refKey, refValue);

            return(await CallClient <K, Tuple <K, string> >(uri, options
                                                            , mapper : (rs, holder) => ExtractHeaders(rs, holder)));
        }
 /// <summary>
 /// This method is used to create an entity in the persistence store.
 /// </summary>
 /// <param name="entity">The entity to create.</param>
 /// <param name="settings">The persistence request settings.</param>
 /// <returns>Returns a response holder that indicates the status of the request and the entity or key and version id where appropriate.</returns>
 public virtual async Task <RepositoryHolder <K, E> > Create(E entity, RepositorySettings settings = null)
 {
     return(await TransmitInternal(EntityActions.Create, new RepositoryHolder <K, E> {
         Entity = entity, Settings = settings
     }, principal : DefaultPrincipal));
 }
Exemple #17
0
        /// <summary>
        /// This method resolves the version id of the entity where supported.
        /// </summary>
        /// <param name="key">The entity unique key.</param>
        /// <param name="options">These are the repository options which define the request type..</param>
        /// <returns>This is the holder containing the response and the entity where necessary.</returns>
        public virtual async Task <RepositoryHolder <K, Tuple <K, string> > > Version(K key, RepositorySettings options = null)
        {
            var uri = mUriMapper.MakeUri(HttpMethod.Head, key);

            return(await CallClient <K, Tuple <K, string> >(uri, options,
                                                            mapper : (rs, holder) => ExtractHeaders(rs, holder, mKeyMapper)));
        }