示例#1
0
        /// <summary>
        /// This method creates a service message and injects it in to the execution path and bypasses the listener infrastructure.
        /// </summary>
        /// <param name="dispatcher">The Microservice dispatcher.</param>
        /// <param name="header">The message header to identify the recipient.</param>
        /// <param name="package">The object package to process.</param>
        /// <param name="ChannelPriority">The priority that the message should be processed. The default is 1. If this message is not a valid value, it will be matched to the nearest valid value.</param>
        /// <param name="options">The process options.</param>
        /// <param name="release">The release action which is called when the payload has been executed by the receiving commands.</param>
        /// <param name="responseHeader">This is the optional response header</param>
        /// <param name="ResponseChannelPriority">This is the response channel priority. This will be set if the response header is not null. The default priority is 1.</param>
        /// <param name="originatorServiceId">This optional parameter allows you to set the originator serviceId</param>
        public static void Process(this IMicroserviceDispatch dispatcher
                                   , ServiceMessageHeader header
                                   , object package                      = null
                                   , int ChannelPriority                 = 1
                                   , ProcessOptions options              = ProcessOptions.RouteExternal | ProcessOptions.RouteInternal
                                   , Action <bool, Guid> release         = null
                                   , ServiceMessageHeader responseHeader = null
                                   , int ResponseChannelPriority         = 1
                                   , string originatorServiceId          = null
                                   )
        {
            var message = new ServiceMessage(header, responseHeader);

            if (originatorServiceId != null)
            {
                message.OriginatorServiceId = originatorServiceId;
            }

            message.ChannelPriority = ChannelPriority;

            message.Holder = ServiceHandlerContext.CreateWithObject(package);
            //if (package != null)
            //    message.Blob = dispatcher.Serialization.PayloadSerialize(package);

            if (responseHeader != null)
            {
                message.ResponseChannelPriority = ResponseChannelPriority;
            }

            dispatcher.Process(message, options, release);
        }
示例#2
0
        /// <summary>
        /// Checks the incoming holder to ensure that it is correctly configured.
        /// </summary>
        /// <param name="holder">The holder.</param>
        /// <returns>Returns true if the checks are passed.</returns>
        /// <exception cref="ArgumentNullException">holder</exception>
        protected virtual bool HolderChecks(ServiceHandlerContext holder)
        {
            if (holder == null)
            {
                throw new ArgumentNullException("holder", "The serialization holder cannot be null.");
            }

            return(holder.Blob != null);
        }
示例#3
0
        /// <summary>
        /// Returns true if the holder can be deserialized.
        /// </summary>
        /// <param name="holder">The holder.</param>
        /// <returns>
        /// Returns true if it can be deserialized.
        /// </returns>
        /// <exception cref="ArgumentNullException">holder</exception>
        public virtual bool SupportsDeserialization(ServiceHandlerContext holder)
        {
            if (holder == null)
            {
                throw new ArgumentNullException("holder");
            }

            return((holder.ContentType?.Id ?? "").Equals(Id, StringComparison.InvariantCultureIgnoreCase));
        }
示例#4
0
        /// <summary>
        /// Returns true if the Content in the holder can be serialized.
        /// </summary>
        /// <param name="holder">The holder.</param>
        /// <returns>
        /// Returns true if it can be serialized.
        /// </returns>
        /// <exception cref="ArgumentNullException">holder</exception>
        public virtual bool SupportsSerialization(ServiceHandlerContext holder)
        {
            if (holder == null)
            {
                throw new ArgumentNullException("holder");
            }

            return(holder.HasObject);
        }
示例#5
0
        /// <summary>
        /// Serializes the specified holder.
        /// </summary>
        /// <param name="holder">The holder.</param>
        /// <exception cref="NotSupportedException">The serialize action is not set.</exception>
        public override void Serialize(ServiceHandlerContext holder)
        {
            if (Serializer == null)
            {
                throw new NotSupportedException("The serialize action is not set.");
            }

            Serializer(holder);
        }
示例#6
0
        /// <summary>
        /// A boolean function that returns true if the compression type is supported.
        /// </summary>
        /// <param name="holder">The serialization holder.</param>
        /// <returns>
        /// Returns true when supported.
        /// </returns>
        /// <exception cref="ArgumentNullException">holder</exception>
        public virtual bool SupportsContentEncoding(ServiceHandlerContext holder)
        {
            if (holder == null)
            {
                throw new ArgumentNullException("holder");
            }

            return(holder.ContentEncoding != null &&
                   string.Equals(holder.ContentEncoding, Id, StringComparison.InvariantCultureIgnoreCase));
        }
        /// <summary>
        /// Tries to compress the outgoing holder.
        /// </summary>
        /// <param name="collection">The collection.</param>
        /// <param name="blob">The binary array.</param>
        /// <returns>Returns true if the Content is serialized correctly to a binary blob.</returns>
        public static O DeserializeToObject <O>(this ServiceHandlerCollection <IServiceHandlerSerialization> collection, byte[] blob)
        {
            ServiceHandlerContext context = blob;

            if (collection.TryDeserialize(context))
            {
                return((O)context.Object);
            }

            throw new PayloadDeserializationException();
        }
        /// <summary>
        /// Tries to compress the outgoing holder.
        /// </summary>
        /// <param name="collection">The collection.</param>
        /// <param name="item">The item.</param>
        /// <returns>Returns true if the Content is serialized correctly to a binary blob.</returns>
        public static byte[] SerializeToBlob(this ServiceHandlerCollection <IServiceHandlerSerialization> collection, object item)
        {
            var context = ServiceHandlerContext.CreateWithObject(item);

            //context.ContentType = collection.
            if (collection.TrySerialize(context))
            {
                return(context.Blob);
            }

            throw new PayloadSerializationException();
        }
示例#9
0
        /// <summary>
        /// Extracts the content encoding in to a matchable format.
        /// </summary>
        /// <param name="holder">The service holder.</param>
        /// <param name="value">The value.</param>
        /// <returns>Returns true if it can be extracted.</returns>
        public static bool ExtractContentEncoding(ServiceHandlerContext holder, out string value)
        {
            value = null;

            if (!holder.HasContentEncoding)
            {
                return(false);
            }

            value = holder.ContentEncoding.Id;
            return(true);
        }
示例#10
0
        public override void Serialize(ServiceHandlerContext holder)
        {
            using (var stream = new MemoryStream())
                using (var streamWriter = new StreamWriter(stream))
                    using (var textWriter = new JsonTextWriter(streamWriter))
                    {
                        mJsonSerializer.Serialize(textWriter, holder.Object);
                        streamWriter.Flush();
                        stream.Position = 0;
                        holder.SetBlob(stream.ToArray());
                    }

            holder.ContentType = Id + $"; type=\"{holder.Object.GetType().ToString()}\"";
        }
示例#11
0
        /// <summary>
        /// This method marshals the RepositoryHolder and transmits it to the remote Microservice.
        /// </summary>
        /// <typeparam Name="KT">The key type.</typeparam>
        /// <typeparam Name="ET">The entity type.</typeparam>
        /// <param Name="actionType">The action type.</param>
        /// <param Name="rq">The repository holder request.</param>
        /// <returns>Returns an async task that will be signalled when the request completes or times out.</returns>
        protected override async Task <RepositoryHolder <KT, ET> > TransmitInternal <KT, ET>(
            string actionType, RepositoryHolder <KT, ET> rq, ProcessOptions?routing = null, IPrincipal principal = null)
        {
            try
            {
                StatisticsInternal.ActiveIncrement();

                var payload = TransmissionPayload.Create(Policy.TransmissionPayloadTraceEnabled);

                payload.SecurityPrincipal = TransmissionPayload.ConvertToClaimsPrincipal(principal ?? Thread.CurrentPrincipal);

                // Set the process correlation key to the correlation id if passed through the rq settings
                if (!string.IsNullOrEmpty(rq.Settings?.CorrelationId))
                {
                    payload.Message.ProcessCorrelationKey = rq.Settings.CorrelationId;
                }

                bool processAsync = rq.Settings?.ProcessAsync ?? false;

                payload.Message.ChannelPriority = processAsync ? 0 : 1;

                payload.Options = routing ?? RoutingDefault ?? ProcessOptions.RouteExternal;

                payload.Message.Holder = ServiceHandlerContext.CreateWithObject(rq);

                payload.Message.ResponseChannelId = ResponseChannelId;

                payload.Message.ResponseChannelId   = ResponseId.Header.ChannelId;
                payload.Message.ResponseMessageType = ResponseId.Header.MessageType;
                payload.Message.ResponseActionType  = ResponseId.Header.ActionType;

                payload.Message.ResponseChannelPriority = payload.Message.ChannelPriority;

                payload.Message.ChannelId   = ChannelId;
                payload.Message.MessageType = EntityType;
                payload.Message.ActionType  = actionType;

                payload.MaxProcessingTime = rq.Settings?.WaitTime ?? mDefaultRequestTimespan;

                return(await OutgoingRequestOut(payload, ProcessResponse <KT, ET>, processAsync));
            }
            catch (Exception ex)
            {
                string key = rq != null && rq.Key != null?rq.Key.ToString() : string.Empty;

                Collector?.LogException($"Error transmitting {actionType}-{key} internally", ex);
                throw;
            }
        }
示例#12
0
        /// <summary>
        /// Returns true if the serializer supports this content type for serialization.
        /// </summary>
        /// <param name="holder">The holder.</param>
        /// <returns>
        /// Returns true if supported.
        /// </returns>
        public virtual bool SupportsContentTypeSerialization(ServiceHandlerContext holder)
        {
            if (!holder.HasObject)
            {
                return(false);
            }

            Type cType = holder.ObjectType ?? holder.Object?.GetType();

            if (cType == null)
            {
                return(false);
            }

            return(SupportsContentTypeSerialization(cType));
        }
示例#13
0
        /// <summary>
        /// Tries to serialize the outgoing payload.
        /// </summary>
        /// <param name="holder">The holder.</param>
        /// <returns>
        /// Returns true if the Content is serialized correctly to a binary blob.
        /// </returns>
        public virtual bool TrySerialize(ServiceHandlerContext holder)
        {
            if (!SupportsSerialization(holder))
            {
                return(false);
            }

            try
            {
                Serialize(holder);
                return(true);
            }
            catch (Exception) { }

            return(false);
        }
示例#14
0
        /// <summary>
        /// Tries to compress the outgoing payload.
        /// </summary>
        /// <param name="holder">The holder.</param>
        /// <returns>
        /// Returns true if the Content is compressed correctly to a binary blob.
        /// </returns>
        public bool TryCompress(ServiceHandlerContext holder)
        {
            string id;

            if (!ExtractContentEncoding(holder, out id))
            {
                return(false);
            }

            IServiceHandlerCompression comp;

            if (!Compression.TryGet(id, out comp))
            {
                return(false);
            }

            return(comp.TryCompression(holder));
        }
示例#15
0
        /// <summary>
        /// Encodes the blobs from compressed to uncompressed.
        /// </summary>
        /// <param name="holder">The holder.</param>
        /// <param name="getStream">The decompress stream create function.</param>
        /// <returns>Returns true if encoded without error.</returns>
        protected virtual bool Decompress(ServiceHandlerContext holder, Func <Stream, Stream> getStream)
        {
            try
            {
                using (MemoryStream msIn = new MemoryStream(holder.Blob))
                    using (Stream decompress = getStream(msIn))
                        using (MemoryStream msOut = new MemoryStream())
                        {
                            decompress.CopyTo(msOut);
                            decompress.Close();
                            holder.SetBlob(msOut.ToArray(), holder.ContentType);
                        }
            }
            catch (Exception ex)
            {
                return(false);
            }

            return(true);
        }
示例#16
0
        /// <summary>
        /// Encodes the blobs from uncompressed to compressed.
        /// </summary>
        /// <param name="holder">The holder.</param>
        /// <param name="getStream">The get compressor stream function.</param>
        /// <param name="contentEncoding">The content encoding parameter.</param>
        /// <returns>Returns true if encoded without error.</returns>
        /// <exception cref="ArgumentNullException">holder</exception>
        protected virtual bool Compress(ServiceHandlerContext holder, Func <Stream, Stream> getStream, string contentEncoding)
        {
            try
            {
                using (MemoryStream ms = new MemoryStream())
                    using (Stream compress = getStream(ms))
                    {
                        compress.Write(holder.Blob, 0, holder.Blob.Length);
                        compress.Close();

                        holder.SetBlob(ms.ToArray(), holder.ContentType, contentEncoding);
                    }
            }
            catch (Exception ex)
            {
                return(false);
            }

            return(true);
        }
示例#17
0
        /// <summary>
        /// Serializes the summary JSON object in the holder and sets the byte array.
        /// </summary>
        /// <param name="holder">The holder to set.</param>
        public override void Serialize(ServiceHandlerContext holder)
        {
            var stats = holder.Object as Microservice.Statistics;

            if (stats == null)
            {
                throw new ArgumentOutOfRangeException("The holder object is not of type MicroserviceStatistics");
            }

            dynamic message = new ExpandoObject();

            message.Id     = stats.Id.ExternalServiceId;
            message.Status = stats.Status;
            message.TS     = DateTime.UtcNow.ToBinary();
            message.Engine = $"{stats.Id.ServiceVersionId}/{stats.Id.ServiceEngineVersionId}";
            message.Uptime = stats.Uptime;

            message.Tasks = stats.Tasks.Message;

            var authorData = JsonConvert.SerializeObject(message);

            holder.SetBlob(Encoding.UTF8.GetBytes(authorData), maxLength: UdpHelper.PacketMaxSize);
        }
示例#18
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SerializationHolderContentTypeException"/> class.
 /// </summary>
 /// <param name="holder">The holder.</param>
 /// <param name="expectedType">The expected content type.</param>
 public SerializationHolderContentTypeException(ServiceHandlerContext holder, string expectedType)
 {
     ContentTypeExpected = expectedType;
     ContentTypeActual   = holder?.ContentType;
 }
示例#19
0
 /// <summary>
 /// Serializes the specified object in the holder and sets the byte array.
 /// </summary>
 /// <param name="holder">The holder.</param>
 public abstract void Serialize(ServiceHandlerContext holder);
示例#20
0
 /// <summary>
 /// Tries to decompress the incoming holder.
 /// </summary>
 /// <param name="holder">The holder.</param>
 /// <returns>
 /// Returns true if the incoming binary payload is successfully decompressed.
 /// </returns>
 /// <exception cref="NotImplementedException"></exception>
 public virtual bool TryDecompression(ServiceHandlerContext holder)
 {
     return(HolderChecks(holder) && Decompress(holder, GetDecompressionStream));
 }
 public override void Serialize(ServiceHandlerContext holder)
 {
     throw new NotImplementedException();
 }
示例#22
0
 public override void Deserialize(ServiceHandlerContext holder)
 {
     //mJsonSerializer.Deserialize(
 }
        /// <summary>
        /// Tries to compress the outgoing holder.
        /// </summary>
        /// <param name="collection">The collection.</param>
        /// <param name="holder">The holder.</param>
        /// <returns>Returns true if the Content is serialized correctly to a binary blob.</returns>
        public static bool TrySerialize(this ServiceHandlerCollection <IServiceHandlerSerialization> collection, ServiceHandlerContext holder)
        {
            string id;

            if (!ServiceHandlerContainer.ExtractContentType(holder, out id))
            {
                return(false);
            }

            IServiceHandlerSerialization sr = null;

            if (!collection.TryGet(id, out sr))
            {
                return(false);
            }

            return(sr.TrySerialize(holder));
        }
示例#24
0
        /// <summary>
        /// This method is used to send requests to the remote command.
        /// </summary>
        /// <typeparam name="RQ">The request type.</typeparam>
        /// <typeparam name="RS">The response type.</typeparam>
        /// <param name="channelId">The header routing information.</param>
        /// <param name="messageType">The header routing information.</param>
        /// <param name="actionType">The header routing information.</param>
        /// <param name="rq">The request object.</param>
        /// <param name="rqSettings">The request settings. Use this to specifically set the timeout parameters.</param>
        /// <param name="routingOptions">The routing options by default this will try internal and then external.</param>
        /// <param name="processResponse"></param>
        /// <param name="fallbackMaxProcessingTime">This is the fallback max processing time used if the timeout
        /// is not set in the request settings.
        /// If this is also null, the max time out will fall back to the policy settings.</param>
        /// <param name="principal">This is the principal that you wish the command to be executed under.
        /// By default this is taken from the calling thread if not passed.</param>
        /// <returns>Returns the async response wrapper.</returns>
        protected internal virtual async Task <ResponseWrapper <RS> > ProcessOutgoing <RQ, RS>(
            string channelId, string messageType, string actionType
            , RQ rq
            , RequestSettings rqSettings    = null
            , ProcessOptions?routingOptions = null
            , Func <TaskStatus, TransmissionPayload, bool, ResponseWrapper <RS> > processResponse = null
            , TimeSpan?fallbackMaxProcessingTime = null
            , IPrincipal principal = null
            )
        {
            if (!Policy.OutgoingRequestsEnabled)
            {
                throw new OutgoingRequestsNotEnabledException();
            }

            TransmissionPayload payload = null;

            try
            {
                StatisticsInternal.ActiveIncrement();

                payload = TransmissionPayload.Create(Policy.TransmissionPayloadTraceEnabled);
                payload.SecurityPrincipal = TransmissionPayload.ConvertToClaimsPrincipal(principal ?? Thread.CurrentPrincipal);

                // Set the process correlation key to the correlation id, if passed through the request settings
                if (!string.IsNullOrEmpty(rqSettings?.CorrelationId))
                {
                    payload.Message.ProcessCorrelationKey = rqSettings.CorrelationId;
                }

                bool processAsync = rqSettings?.ProcessAsync ?? false;

                payload.Options = routingOptions ?? ProcessOptions.RouteExternal | ProcessOptions.RouteInternal;

                //Set the destination message
                payload.Message.ChannelId       = channelId ?? ChannelId;
                payload.Message.MessageType     = messageType;
                payload.Message.ActionType      = actionType;
                payload.Message.ChannelPriority = processAsync ? 0 : 1;

                //Set the response path
                payload.Message.ResponseChannelId       = ResponseId.Header.ChannelId;
                payload.Message.ResponseMessageType     = ResponseId.Header.MessageType;
                payload.Message.ResponseActionType      = ResponseId.Header.ActionType;
                payload.Message.ResponseChannelPriority = payload.Message.ChannelPriority;

                //Set the payload
                payload.Message.Holder = ServiceHandlerContext.CreateWithObject(rq);

                //Set the processing time
                payload.MaxProcessingTime = rqSettings?.WaitTime ?? fallbackMaxProcessingTime ?? Policy.OutgoingRequestMaxProcessingTimeDefault;

                //Transmit
                return(await OutgoingRequestOut(payload, processResponse ?? ProcessOutgoingResponse <RS>, processAsync));
            }
            catch (Exception ex)
            {
                string key = payload?.Id.ToString() ?? string.Empty;
                Collector?.LogException(string.Format("Error transmitting {0}-{1} internally", actionType, key), ex);
                throw;
            }
        }
 /// <summary>
 /// Checks that a specific serializer is supported.
 /// </summary>
 /// <param name="collection">The collection.</param>
 /// <param name="holder">The holder.</param>
 /// <returns>Returns true when the holder ContentType is supported.</returns>
 public static bool SupportsSerializer(this ServiceHandlerCollection <IServiceHandlerSerialization> collection, ServiceHandlerContext holder)
 {
     return(collection.Contains(holder.ContentType));
 }
 protected virtual void WriteEntity(FileStream fs, E entity)
 {
     var json   = Transform.JsonMaker(entity);
     var holder = ServiceHandlerContext.CreateWithObject(entity);
 }
示例#27
0
 /// <summary>
 /// Tries to compress the outgoing payload.
 /// </summary>
 /// <param name="holder">The holder.</param>
 /// <returns>
 /// Returns true if the Content is compressed correctly to a binary blob.
 /// </returns>
 /// <exception cref="NotImplementedException"></exception>
 public virtual bool TryCompression(ServiceHandlerContext holder)
 {
     return(HolderChecks(holder) && Compress(holder, GetCompressionStream, Id));
 }
示例#28
0
 /// <summary>
 /// Returns true if the Content in the holder can be serialized.
 /// </summary>
 /// <param name="holder">The holder.</param>
 /// <returns>
 /// Returns true if it can be serialized.
 /// </returns>
 public override bool SupportsSerialization(ServiceHandlerContext holder)
 {
     return(Serializer != null &&
            (FnCanSerialize?.Invoke(holder) ?? true) &&
            base.SupportsSerialization(holder));
 }
示例#29
0
 /// <summary>
 /// Returns true if the Content in the holder can be serialized.
 /// </summary>
 /// <param name="holder">The holder.</param>
 /// <returns>
 /// Returns true if it can be serialized.
 /// </returns>
 public override bool SupportsSerialization(ServiceHandlerContext holder)
 {
     return(base.SupportsSerialization(holder) && holder.ObjectType == typeof(Microservice.Statistics));
 }