예제 #1
0
        /// <summary>
        /// Adds the specified facts into the internal collection by serializing these using DataContractSerializer.
        /// </summary>
        /// <param name="facts">A collection of facts.</param>
        public void AddFacts(IEnumerable <object> facts)
        {
            Guard.ArgumentNotNull(facts, "facts");

            foreach (object fact in facts)
            {
                var dcAttribute = FrameworkUtility.GetDeclarativeAttribute <DataContractAttribute>(fact);

                if (dcAttribute != null)
                {
                    DataContractSerializer serializer = !String.IsNullOrEmpty(dcAttribute.Name) && !String.IsNullOrEmpty(dcAttribute.Namespace) ? new DataContractSerializer(fact.GetType(), dcAttribute.Name, dcAttribute.Namespace) : new DataContractSerializer(fact.GetType());

                    using (MemoryStream serializationBuffer = new MemoryStream())
                    {
                        using (var xmlWriter = XmlDictionaryWriter.CreateTextWriter(serializationBuffer, Encoding.UTF8, false))
                        {
                            serializer.WriteObject(xmlWriter, fact);
                        }

                        serializationBuffer.Seek(0, SeekOrigin.Begin);

                        using (StreamReader dataReader = new StreamReader(serializationBuffer))
                        {
                            this.facts[fact.GetType().AssemblyQualifiedName] = dataReader.ReadToEnd();
                        }
                    }
                }
                else
                {
                    throw new InvalidDataContractException(String.Format(CultureInfo.InvariantCulture, ExceptionMessages.MustSupplyDataContractAttribute, fact.GetType().FullName));
                }
            }
        }
예제 #2
0
        private void DeserializeSection(ApplicationConfigurationSettings source)
        {
            using (MemoryStream memoryBuffer = new MemoryStream())
            {
                XmlWriterSettings writerRettings = new XmlWriterSettings();

                writerRettings.CloseOutput       = false;
                writerRettings.CheckCharacters   = false;
                writerRettings.ConformanceLevel  = ConformanceLevel.Fragment;
                writerRettings.NamespaceHandling = NamespaceHandling.OmitDuplicates;

                using (XmlWriter writer = XmlWriter.Create(memoryBuffer, writerRettings))
                {
                    source.WriteXml(writer);
                    writer.Flush();
                }

                memoryBuffer.Seek(0, SeekOrigin.Begin);

                XmlDocument       configXml      = FrameworkUtility.CreateXmlDocument(memoryBuffer);
                XmlReaderSettings readerSettings = new XmlReaderSettings();

                readerSettings.CloseInput                   = false;
                readerSettings.IgnoreWhitespace             = true;
                readerSettings.IgnoreComments               = true;
                readerSettings.ValidationType               = ValidationType.None;
                readerSettings.IgnoreProcessingInstructions = true;

                using (XmlReader reader = XmlReader.Create(new StringReader(configXml.OuterXml), readerSettings))
                {
                    this.ReadXml(reader);
                }
                this.PostDeserialize();
            }
        }
예제 #3
0
        /// <summary>
        /// Returns a setting value from the application configuration settings by its key name casting the return value to the specified type <typeparamref name="T"/>.
        /// </summary>
        /// <typeparam name="T">The type of the configuration setting.</typeparam>
        /// <param name="key">The value containing the setting's key name.</param>
        /// <param name="defaultValue">The default value to be used when configuration setting's value is null or the setting was not found.</param>
        /// <returns>The setting's value or the specified default value if the specified key was not found.</returns>
        public T GetSetting <T>(string key, T defaultValue)
        {
            Guard.ArgumentNotNullOrEmptyString(key, "key");

            KeyValueConfigurationElement value = Settings[GetNormalizedKey(key)];

            return(value != null?FrameworkUtility.ConvertTo <T>(value.Value) : defaultValue);
        }
예제 #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="AboutViewModel"/> class.
        /// </summary>
        /// <param name="dll">The DLL.</param>
        public AboutViewModel(Assembly dll)
        {
            this.SetProperties(dll);

            this.AboutCommand = new DelegateCommand(() =>
            {
                var location = "http://songhaysystem.com/"; //TODO: add About… (documentation) support for songhaysystem.com
                FrameworkUtility.StartProcess(location, string.Empty, false);
            });
        }
예제 #5
0
 private XmlObjectSerializer GetXmlSerializer(Type type)
 {
     if (FrameworkUtility.GetDeclarativeAttribute <DataContractAttribute>(type) != null)
     {
         return(new DataContractSerializer(type));
     }
     else
     {
         return(new NetDataContractSerializer());
     }
 }
예제 #6
0
        static void Main()
        {
            var versionString = "1.0.0-prerelease";
            var frameworkName = "netstandard2.0";

            Console.WriteLine("Hello World!");
            Console.WriteLine("Calling into Library1");
            Console.WriteLine($"The prelease label for {versionString} is {VersioningUtility.GetPrereleaseLabel(versionString)}");
            Console.WriteLine("Calling into Library2");
            Console.WriteLine($"The framework name for {frameworkName} is {FrameworkUtility.GetCanonicalFrameworkName(frameworkName)}");
            Console.WriteLine("Done!");
        }
예제 #7
0
        /// <summary>
        /// Returns an instance of a trace provider for the specified type. This requires that the type supplies its Guid which will be used
        /// for registering it with the ETW infrastructure.
        /// </summary>
        /// <param name="componentType">The type which must be decarated with a GuidAttribute</param>
        /// <returns>An instance of a trace provider implementing the IComponentTraceProvider interface</returns>
        public static IComponentTraceProvider Create(Type componentType)
        {
            GuidAttribute guidAttribute = FrameworkUtility.GetDeclarativeAttribute <GuidAttribute>(componentType);

            if (guidAttribute != default(GuidAttribute))
            {
                return(new ComponentTraceProvider(componentType.FullName, new Guid(guidAttribute.Value)));
            }
            else
            {
                throw new MissingMemberException(componentType.FullName, typeof(GuidAttribute).FullName);
            }
        }
예제 #8
0
        private static ServiceHost CreateServiceBusHost(string serviceNamespace, string servicePath, string issuerName, string issuerSecret, Binding binding, Type serviceType)
        {
            Guard.ArgumentNotNullOrEmptyString(serviceNamespace, "serviceNamespace");
            Guard.ArgumentNotNullOrEmptyString(servicePath, "servicePath");
            Guard.ArgumentNotNullOrEmptyString(issuerName, "issuerName");
            Guard.ArgumentNotNullOrEmptyString(issuerSecret, "issuerSecret");
            Guard.ArgumentNotNull(binding, "binding");

            var callToken = TraceManager.DebugComponent.TraceIn(serviceNamespace, servicePath, binding.Name);

            var address = ServiceBusEnvironment.CreateServiceUri(WellKnownProtocolScheme.ServiceBus, serviceNamespace, servicePath);

            var credentialsBehaviour = new TransportClientEndpointBehavior();

            credentialsBehaviour.CredentialType = TransportClientCredentialType.SharedSecret;
            credentialsBehaviour.Credentials.SharedSecret.IssuerName   = issuerName;
            credentialsBehaviour.Credentials.SharedSecret.IssuerSecret = issuerSecret;

            var endpoint = new ServiceEndpoint(ContractDescription.GetContract(GetServiceContract(serviceType)), binding, new EndpointAddress(address));

            endpoint.Behaviors.Add(credentialsBehaviour);

            // Apply default endpoint configuration.
            ServiceEndpointConfiguration.ConfigureDefaults(endpoint);

            ServiceBehaviorAttribute serviceBehaviorAttr = FrameworkUtility.GetDeclarativeAttribute <ServiceBehaviorAttribute>(serviceType);
            ServiceHost host = null;

            if (serviceBehaviorAttr != null && serviceBehaviorAttr.InstanceContextMode == InstanceContextMode.Single)
            {
                host = new ServiceHost(Activator.CreateInstance(serviceType));
            }
            else
            {
                host = new ServiceHost(serviceType);
            }

            host.Description.Endpoints.Add(endpoint);
#if DEBUG
            var debugBehavior = new ServiceDebugBehavior();
            debugBehavior.IncludeExceptionDetailInFaults = true;

            host.Description.Behaviors.Remove <ServiceDebugBehavior>();
            host.Description.Behaviors.Add(debugBehavior);
#endif
            TraceManager.DebugComponent.TraceOut(callToken, endpoint.Address.Uri);

            return(host);
        }
예제 #9
0
 /// <summary>
 /// Creates a new instance of the inter-role communication event with the specified payload and deployment ID, role name and role instance ID that identify the recipient.
 /// </summary>
 /// <param name="payload">The event payload.</param>
 /// <param name="deploymentID">The deployment ID identifying a hosted service in which the recipients for the inter-role communication event are deployed.</param>
 /// <param name="roleName">The name identifying a role to which inter-role communication event recipient belong.</param>
 /// <param name="roleInstanceID">The role instance ID uniquely identifying a particular recipient of the inter-role communication event.</param>
 public InterRoleCommunicationEvent(object payload, string deploymentID = null, string roleName = null, string roleInstanceID = null) : this(payload)
 {
     // Check of role instance ID was specified.
     if (!String.IsNullOrEmpty(roleInstanceID))
     {
         // If role instance ID is specified, use a combination of deployment ID and role instance ID to determine where to send.
         To = FrameworkUtility.GetHashedValue(deploymentID ?? CloudEnvironment.DeploymentId, roleInstanceID);
     }
     else if (!String.IsNullOrEmpty(roleName))
     {
         // If role instance ID is not provided but name was specified instead, assume that the event is to be sent to all instances of a particular role.
         To = FrameworkUtility.GetHashedValue(deploymentID ?? CloudEnvironment.DeploymentId, roleName);
     }
     // Otherwise, treat this event as a multicast event and do not set the To property.
 }
예제 #10
0
        private void ConfigureServiceHostWorkerRole(IExtensibleCloudServiceComponent ownerRole)
        {
            var callToken = TraceManager.WorkerRoleComponent.TraceIn(ownerRole != null ? ownerRole.GetType().FullName : null);
            var startScopeCreateServiceHosts = TraceManager.WorkerRoleComponent.TraceStartScope(TraceLogMessages.ScopeCreateServiceHosts, callToken);

            if (ownerRole != null)
            {
                IList <ServiceBusHostWorkerRoleAttribute> serviceHostAttributes = FrameworkUtility.GetDeclarativeAttributes <ServiceBusHostWorkerRoleAttribute>(ownerRole.GetType());
                IRoleConfigurationSettingsExtension       roleConfigExtension   = ownerRole.Extensions.Find <IRoleConfigurationSettingsExtension>();

                if (serviceHostAttributes != null && serviceHostAttributes.Count > 0 && roleConfigExtension != null)
                {
                    ServiceBusEndpointInfo         endpointInfo = null;
                    ServiceBusListenerRegistration listenerInfo = null;

                    foreach (ServiceBusHostWorkerRoleAttribute serviceHostAttr in serviceHostAttributes)
                    {
                        endpointInfo = roleConfigExtension.GetServiceBusEndpoint(serviceHostAttr.ServiceBusEndpoint);

                        if (endpointInfo != null)
                        {
                            listenerInfo = new ServiceBusListenerRegistration()
                            {
                                ServiceType  = serviceHostAttr.ServiceType,
                                EndpointInfo = endpointInfo,
                                AutoStart    = serviceHostAttr.AutoStart
                            };

                            // All services that are enabled for auto-start will have their service hosts pre-initialized but not as yet openned.
                            if (listenerInfo.AutoStart)
                            {
                                TraceManager.WorkerRoleComponent.TraceInfo(TraceLogMessages.AboutToCreateServiceHost, listenerInfo.ServiceType.FullName, endpointInfo.Name, endpointInfo.ServiceNamespace, endpointInfo.ServicePath, endpointInfo.EndpointType);
                                listenerInfo.ServiceHost = new ReliableServiceBusHost <object>(ServiceBusHostFactory.CreateServiceBusHost(endpointInfo, listenerInfo.ServiceType), roleConfigExtension.CommunicationRetryPolicy);
                            }

                            this.serviceEndpoints.Add(endpointInfo, listenerInfo);
                        }
                        else
                        {
                            throw new CloudApplicationException(String.Format(CultureInfo.CurrentCulture, ExceptionMessages.SpecifiedServiceBusEndpointNotFound, serviceHostAttr.ServiceBusEndpoint, ServiceBusConfigurationSettings.SectionName));
                        }
                    }
                }
            }

            TraceManager.WorkerRoleComponent.TraceEndScope(TraceLogMessages.ScopeCreateServiceHosts, startScopeCreateServiceHosts, callToken);
            TraceManager.WorkerRoleComponent.TraceOut(callToken);
        }
예제 #11
0
        /// <summary>
        /// Reconstructs an instance of a <see cref="TraceEventRecord"/> object from its XML representation generated by <see cref="System.Runtime.Serialization.DataContractSerializer"/>.
        /// </summary>
        /// <param name="reader">The XML reader supplying the serialized representation of a <see cref="TraceEventRecord"/> object.</param>
        /// <returns>The initialized instance of a <see cref="TraceEventRecord"/> object containing trace event details.</returns>
        public static TraceEventRecord Create(XmlReader reader)
        {
            Guard.ArgumentNotNull(reader, "reader");

            DataContractAttribute dataContractAttr = FrameworkUtility.GetDeclarativeAttribute <DataContractAttribute>(typeof(TraceEventRecord));

            if (dataContractAttr != null)
            {
                XElement eventRecordXml = XElement.Load(reader, LoadOptions.None);

                if (eventRecordXml.Name.LocalName == dataContractAttr.Name && eventRecordXml.Name.Namespace == dataContractAttr.Namespace)
                {
                    XElement childElement;

                    TraceEventRecord eventRecord = new TraceEventRecord
                    {
                        DateTime = (childElement = (from child in eventRecordXml.Descendants(XName.Get(DateTimePropertyName, dataContractAttr.Namespace)) select child).FirstOrDefault()) != null?DateTime.Parse(childElement.Value, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal) : default(DateTime),
                                       ProcessId = (childElement = (from child in eventRecordXml.Descendants(XName.Get(ProcessIdPropertyName, dataContractAttr.Namespace)) select child).FirstOrDefault()) != null?Int32.Parse(childElement.Value, CultureInfo.InvariantCulture) : 0,
                                                       ThreadId = (childElement = (from child in eventRecordXml.Descendants(XName.Get(ThreadIdPropertyName, dataContractAttr.Namespace)) select child).FirstOrDefault()) != null?Int32.Parse(childElement.Value, CultureInfo.InvariantCulture) : 0,
                                                                      MachineName                           = (childElement = (from child in eventRecordXml.Descendants(XName.Get(MachineNamePropertyName, dataContractAttr.Namespace)) select child).FirstOrDefault()) != null ? childElement.Value : null,
                                                                      ProcessName                           = (childElement = (from child in eventRecordXml.Descendants(XName.Get(ProcessNamePropertyName, dataContractAttr.Namespace)) select child).FirstOrDefault()) != null ? childElement.Value : null,
                                                                      Timestamp                             = (childElement = (from child in eventRecordXml.Descendants(XName.Get(TimestampPropertyName, dataContractAttr.Namespace)) select child).FirstOrDefault()) != null?Int64.Parse(childElement.Value, CultureInfo.InvariantCulture) : 0,
                                                                                                    EventId = (childElement = (from child in eventRecordXml.Descendants(XName.Get(EventIdPropertyName, dataContractAttr.Namespace)) select child).FirstOrDefault()) != null?Int32.Parse(childElement.Value, CultureInfo.InvariantCulture) : 0,
                                                                                                                  EventSource   = (childElement = (from child in eventRecordXml.Descendants(XName.Get(EventSourcePropertyName, dataContractAttr.Namespace)) select child).FirstOrDefault()) != null ? childElement.Value : null,
                                                                                                                  EventSourceId = (childElement = (from child in eventRecordXml.Descendants(XName.Get(EventSourceIdPropertyName, dataContractAttr.Namespace)) select child).FirstOrDefault()) != null?Guid.Parse(childElement.Value) : Guid.Empty,
                                                                                                                                      EventType = (childElement = (from child in eventRecordXml.Descendants(XName.Get(EventTypePropertyName, dataContractAttr.Namespace)) select child).FirstOrDefault()) != null ? (TraceEventType)Enum.Parse(typeof(TraceEventType), childElement.Value, true) : default(TraceEventType),
                                                                                                                                      Message   = (childElement = (from child in eventRecordXml.Descendants(XName.Get(MessagePropertyName, dataContractAttr.Namespace)) select child).FirstOrDefault()) != null ? childElement.Value : null
                    };

                    return(eventRecord);
                }
                else
                {
                    throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, ExceptionMessages.CannotCreateInstanceFromXmlReader, typeof(TraceEventRecord).Name, dataContractAttr.Namespace, eventRecordXml.Name.LocalName, eventRecordXml.Name.Namespace), "reader");
                }
            }
            else
            {
                throw new ArgumentNullException(typeof(DataContractAttribute).FullName);
            }
        }
예제 #12
0
        private static Type GetServiceContract(Type serviceType)
        {
            Guard.ArgumentNotNull(serviceType, "serviceType");

            Type[] serviceInterfaces = serviceType.GetInterfaces();

            if (serviceInterfaces != null && serviceInterfaces.Length > 0)
            {
                foreach (Type serviceInterface in serviceInterfaces)
                {
                    ServiceContractAttribute serviceContractAttr = FrameworkUtility.GetDeclarativeAttribute <ServiceContractAttribute>(serviceInterface);

                    if (serviceContractAttr != null)
                    {
                        return(serviceInterface);
                    }
                }
            }

            return(null);
        }
예제 #13
0
        /// <summary>
        /// Adds a new trace listener associated with an unique name and a type containing the implementation.
        /// </summary>
        /// <param name="name">The unique name under which a new trace listener will be added to the collection.</param>
        /// <param name="listenerType">The type implementing the new trace listener.</param>
        public void AddTraceListener(string name, Type listenerType)
        {
            Guard.ArgumentNotNullOrEmptyString(name, "name");
            Guard.ArgumentNotNull(listenerType, "listenerType");

            ConfigurationElementTypeAttribute configElementTypeAttr = FrameworkUtility.GetDeclarativeAttribute <ConfigurationElementTypeAttribute>(listenerType);

            if (configElementTypeAttr != null)
            {
                TraceListenerData listenerData = Activator.CreateInstance(configElementTypeAttr.ConfigurationType) as TraceListenerData;

                if (listenerData != null)
                {
                    listenerData.ListenerDataType = configElementTypeAttr.ConfigurationType;
                    listenerData.Name             = name;
                    listenerData.Type             = listenerType;

                    this.loggingSettings.TraceListeners.Add(listenerData);
                }
            }
        }
예제 #14
0
 /// <summary>
 /// Initializes a new instance of the <see cref="InterRoleCommunicationExtension"/> object with default settings.
 /// </summary>
 public InterRoleCommunicationExtension()
 {
     // Initialize internal fields.
     this.settings         = InterRoleCommunicationSettings.Default;
     this.senderInstanceID = FrameworkUtility.GetHashedValue(CloudEnvironment.DeploymentId, CloudEnvironment.CurrentRoleInstanceId);
 }
예제 #15
0
        private ConfigurationSection RetrieveSection(string sectionName)
        {
            var callToken = TraceManager.DebugComponent.TraceIn(sectionName);

            try
            {
                using (ReliableServiceBusClient <IOnPremiseConfigurationServiceChannel> configServiceClient = new ReliableServiceBusClient <IOnPremiseConfigurationServiceChannel>(this.sbEndpointInfo, this.retryPolicy))
                {
                    var startScopeInvokeService = TraceManager.DebugComponent.TraceStartScope(Resources.ScopeOnPremiseConfigurationSourceInvokeService, callToken);

                    try
                    {
                        // Invoke the WCF service in a reliable fashion and retrieve the specified configuration section.
                        XmlElement configSectionXml = configServiceClient.RetryPolicy.ExecuteAction <XmlElement>(() =>
                        {
                            return(configServiceClient.Client.GetConfigurationSection(sectionName, CloudEnvironment.CurrentRoleName, CloudEnvironment.CurrentRoleMachineName));
                        });

                        if (configSectionXml != null)
                        {
                            // Instantiate a configuration object that correspond to the specified section.
                            ConfigurationSection configSection = ConfigurationSectionFactory.GetSection(sectionName);

                            // Gotcha: configuration section deserializer requires a well-formed XML document including processing instruction.
                            XmlDocument configXml = FrameworkUtility.CreateXmlDocument();
                            configXml.AppendChild(configXml.ImportNode(configSectionXml, true));

                            // Configure XML reader settings to disable validation and ignore certain XML entities.
                            XmlReaderSettings settings = new XmlReaderSettings
                            {
                                CloseInput                   = true,
                                IgnoreWhitespace             = true,
                                IgnoreComments               = true,
                                ValidationType               = ValidationType.None,
                                IgnoreProcessingInstructions = true
                            };

                            // Create a reader to consume the XML data.
                            using (XmlReader reader = XmlReader.Create(new StringReader(configXml.OuterXml), settings))
                            {
                                // Attempt to cast the configuration section object into SerializableConfigurationSection for further check.
                                SerializableConfigurationSection serializableSection = configSection as SerializableConfigurationSection;

                                // Check if the the configuration section natively supports serialization/de-serialization.
                                if (serializableSection != null)
                                {
                                    // Yes, it's supported. Invoke the ReadXml method to consume XML and turn it into object model.
                                    serializableSection.ReadXml(reader);
                                }
                                else
                                {
                                    // No, it's unsupported. Need to do something different, starting with positioning the XML reader to the first available node.
                                    reader.Read();

                                    // Invoke the DeserializeSection method via reflection. This is the only way as the method is internal.
                                    MethodInfo info = configSection.GetType().GetMethod(WellKnownContractMember.MethodNames.DeserializeSection, BindingFlags.NonPublic | BindingFlags.Instance);
                                    info.Invoke(configSection, new object[] { reader });
                                }

                                reader.Close();
                            }

                            if (SourceChanged != null)
                            {
                                SourceChanged(this, new ConfigurationSourceChangedEventArgs(this, new string[] { sectionName }));
                            }

                            return(configSection);
                        }
                        else
                        {
                            // The specified section is not supported by the remote configuration source. We should not throw an exception and rely on the caller to handle an empty section.
                            return(null);
                        }
                    }
                    finally
                    {
                        TraceManager.DebugComponent.TraceEndScope(Resources.ScopeOnPremiseConfigurationSourceInvokeService, startScopeInvokeService, callToken);
                    }
                }
            }
            catch (Exception ex)
            {
                TraceManager.DebugComponent.TraceError(ex, callToken);
                throw;
            }
            finally
            {
                TraceManager.DebugComponent.TraceOut(callToken);
            }
        }
예제 #16
0
        /// <summary>
        /// Constructs and returns a queue name that is unique for the specified instance ID and is safe to be used as a name for the Windows Azure Service Bus Message Buffer.
        /// </summary>
        /// <param name="instanceId">A string that uniquely and reliably identifies the process in which the OnPremisesBufferedTraceListener trace listener is running.</param>
        /// <returns>The constructed queue name.</returns>
        private static string GetServiceBusQueueName(string instanceId)
        {
            Guard.ArgumentNotNullOrEmptyString(instanceId, "instanceId");

            return(CloudUtility.CleanupContainerName(String.Concat(Resources.OnPremisesBufferedTraceListenerQueueName, "-", FrameworkUtility.GetHashedValue(instanceId)).ToLowerInvariant()));
        }
예제 #17
0
        /// <summary>
        /// Initializes a new instance of a <see cref="InterRoleCommunicationExtension"/> object with the specified Service Bus topic endpoint and custom settings.
        /// </summary>
        /// <param name="serviceBusEndpoint">The Service Bus topic endpoint using which this component will be providing inter-role communication.</param>
        /// <param name="settings">The <see cref="InterRoleCommunicationSettings"/> object containing behavioral and runtime settings for the inter-role communication component.</param>
        public InterRoleCommunicationExtension(ServiceBusEndpointInfo serviceBusEndpoint, InterRoleCommunicationSettings settings)
        {
            Guard.ArgumentNotNull(serviceBusEndpoint, "serviceBusEndpoint");
            Guard.ArgumentNotNull(settings, "settings");
            Guard.ArgumentNotNullOrEmptyString(serviceBusEndpoint.TopicName, "serviceBusEndpoint.TopicName");

            // Initialize internal fields.
            this.settings           = settings;
            this.serviceBusEndpoint = serviceBusEndpoint;
            this.retryPolicy        = this.settings.RetryPolicy ?? RetryPolicy.NoRetry;
            this.senderRoleID       = FrameworkUtility.GetHashedValue(CloudEnvironment.DeploymentId, CloudEnvironment.CurrentRoleName);
            this.senderInstanceID   = FrameworkUtility.GetHashedValue(CloudEnvironment.DeploymentId, CloudEnvironment.CurrentRoleInstanceId);

            // Configure Service Bus credentials and service namespace URI.
            var credentials = TokenProvider.CreateSharedSecretTokenProvider(serviceBusEndpoint.IssuerName, serviceBusEndpoint.IssuerSecret);
            var address     = ServiceBusEnvironment.CreateServiceUri("sb", serviceBusEndpoint.ServiceNamespace, String.Empty);

            // Configure Service Bus messaging factory and namespace client which is required for subscription management.
            this.messagingFactory = MessagingFactory.Create(address, credentials);
            this.nsManager        = new NamespaceManager(address, credentials);

            // Figure out the name of the subscription. If subscription name was specified in the endpoint definition, treat it as static.
            // If no subscription name was specified, assign a globally unique name based on hashed deployment ID and role instance ID values.
            this.useStaticSubscription = !String.IsNullOrEmpty(serviceBusEndpoint.SubscriptionName);
            this.ircSubscriptionName   = this.useStaticSubscription ? serviceBusEndpoint.SubscriptionName : (this.settings.UseCompetingConsumers ? String.Concat(SubscriptionNamePrefix, this.senderRoleID) : String.Concat(SubscriptionNamePrefix, this.senderInstanceID));

            // Configure the underlying messaging entities such as topic and subscription.
            ConfigureTopicClient(this.serviceBusEndpoint.TopicName);
            ConfigureSubscriptionClient(this.ircSubscriptionName);

            // Configure a fault handler for the receive action.
            this.receiveFaultAction = ((msg, ex) =>
            {
                // Log an error.
                TraceManager.ServiceComponent.TraceError(ex);

                try
                {
                    if (msg != null)
                    {
                        // Abandons a brokered message. This will cause Service Bus to unlock the message and make it available to be received again,
                        // either by the same consumer or by another completing consumer.
                        msg.Abandon(this.retryPolicy);
                    }
                }
                catch (MessageLockLostException)
                {
                    // It's too late to compensate the loss of a message lock. Should just ignore it so that it does not break the receive loop.
                }
                catch (CommunicationObjectAbortedException)
                {
                    // There is nothing we can do as connection might have been lost or underlying topic/subscription might have been removed.
                }
                catch (CommunicationObjectFaultedException)
                {
                    // If Abandon fail with this exception, the only recourse is to Receive another message (possibly the same one).
                }
            });

            // Configure event receive action.
            this.receiveAction = (() =>
            {
                BrokeredMessage msg = null;
                bool completedAsync = false;

                this.retryPolicy.ExecuteAction(() =>
                {
                    // Make sure we are not told to stop receiving while we are retrying.
                    if (!cts.IsCancellationRequested)
                    {
#if PERF_TEST
                        Stopwatch watch = Stopwatch.StartNew();
#endif
                        if ((msg = this.subscriptionClient.Receive(this.settings.EventWaitTimeout)) != null)
                        {
#if PERF_TEST
                            watch.Stop();
                            TraceManager.ServiceComponent.TraceDetails("Waited for a new event for {0}ms", watch.ElapsedMilliseconds);
#endif
                            try
                            {
                                // Make sure we are not told to stop receiving while we were waiting for a new message.
                                if (!this.cts.IsCancellationRequested)
                                {
                                    if (this.settings.EnableAsyncDispatch)
                                    {
                                        // Invoke the dispatch action asynchronously.
                                        this.dispatchAction.BeginInvoke(msg, this.endDispatch, msg);

                                        completedAsync = true;
                                    }
                                    else
                                    {
                                        // Invoke the dispatch action synchronously.
                                        this.dispatchAction(msg);

                                        // Mark brokered message as complete.
                                        msg.Complete(this.retryPolicy);
                                    }
                                }
                                else
                                {
                                    // If we were told to stop processing, the current message needs to be unlocked and return back to the queue.
                                    msg.Abandon(this.retryPolicy);
                                }
                            }
                            catch (Exception ex)
                            {
                                this.receiveFaultAction(msg, ex);
                            }
                            finally
                            {
                                // Do not attempt to dispose a BrokeredMessage instance if it was dispatched for processing asynchronously.
                                if (msg != null && !completedAsync)
                                {
                                    // Ensure that any resources allocated by a BrokeredMessage instance are released.
                                    msg.Dispose();
                                }
                            }
                        }
                    }
                });
            });

            // Configure event receive complete action.
            this.endReceive = ((ar) =>
            {
                try
                {
                    this.receiveAction.EndInvoke(ar);
                }
                catch (Exception ex)
                {
                    // Log this error. Do not allow an unhandled exception to kill the current process.
                    TraceManager.ServiceComponent.TraceError(ex);
                }

                if (!cts.IsCancellationRequested)
                {
                    this.receiveHandle = this.receiveAction.BeginInvoke(this.endReceive, null);
                }
            });

            // Configure event dispatch action. This action is performed when notifying subscribers about a new IRC event.
            this.dispatchAction = ((msg) =>
            {
                // Extract the event data from brokered message.
                InterRoleCommunicationEvent e = msg.GetBody <InterRoleCommunicationEvent>(this.serializer);

                // Notify all registered subscribers.
                NotifySubscribers(e);
            });

            this.endDispatch = ((ar) =>
            {
                BrokeredMessage msg = null;

                try
                {
                    msg = ar.AsyncState as BrokeredMessage;
                    this.dispatchAction.EndInvoke(ar);

                    if (msg != null)
                    {
                        // Mark brokered message as complete.
                        msg.Complete(this.retryPolicy);
                    }
                }
                catch (Exception ex)
                {
                    this.receiveFaultAction(msg, ex);
                }
                finally
                {
                    if (msg != null)
                    {
                        // Ensure that any resources allocated by a BrokeredMessage instance are released.
                        msg.Dispose();
                    }
                }
            });
        }
예제 #18
0
 /// <summary>
 /// Creates a new instance of the multicast inter-role communication event with the specified payload.
 /// </summary>
 /// <param name="payload">The event payload.</param>
 public InterRoleCommunicationEvent(object payload)
 {
     From       = FrameworkUtility.GetHashedValue(CloudEnvironment.DeploymentId, CloudEnvironment.CurrentRoleInstanceId);
     Properties = new Dictionary <string, object>();
     Payload    = payload;
 }