/// <summary> /// Notifies this extension component that it has been unregistered from the owner's collection of extensions. /// </summary> /// <param name="owner">The extensible owner object that aggregates this extension.</param> public void Detach(IExtensibleCloudServiceComponent owner) { if (this.publisher != null) { this.publisher.Dispose(); this.publisher = null; } }
/// <summary> /// Performs application-defined tasks associated with freeing, releasing, or resetting managed and unmanaged resources. /// </summary> public void Dispose() { if (this.activityTrackingClient != null) { this.activityTrackingClient.Dispose(); this.activityTrackingClient = null; } }
/// <summary> /// Notifies this extension component that it has been registered in the owner's collection of extensions. /// </summary> /// <param name="owner">The extensible owner object that aggregates this extension.</param> public void Attach(IExtensibleCloudServiceComponent owner) { IRoleConfigurationSettingsExtension roleConfigExtension = owner.Extensions.Find <IRoleConfigurationSettingsExtension>(); if (roleConfigExtension != null) { this.activityTrackingClient = new ReliableServiceBusClient <IActivityTrackingServiceChannel>(roleConfigExtension.OnPremiseRelayOneWayEndpoint, roleConfigExtension.CommunicationRetryPolicy); } }
private void SubmitApplication(LoanApplicationData loanApp) { LoanApplicationProcess loanRequestActivity = new LoanApplicationProcess(loanApp.ApplicationID) { ApplicantID = loanApp.Ssn, LoanApplicationSubmitted = DateTime.UtcNow }; // Ensure the availability of required extensions, throw an exception if not available. Global.WebRoleSingleton.Extensions.Demand <IActivityTrackingEventStreamExtension>(); Global.WebRoleSingleton.Extensions.Demand <IRulesEngineServiceClientExtension>(); IActivityTrackingEventStreamExtension trackingEventStream = Global.WebRoleSingleton.Extensions.Find <IActivityTrackingEventStreamExtension>(); IRulesEngineServiceClientExtension ruleEngineClient = Global.WebRoleSingleton.Extensions.Find <IRulesEngineServiceClientExtension>(); IRoleConfigurationSettingsExtension roleConfig = Global.WebRoleSingleton.Extensions.Find <IRoleConfigurationSettingsExtension>(); // Tells the event stream to invoke the BeginActivity operation. trackingEventStream.BeginActivity(loanRequestActivity); // Call BRE rule to obtain a pre-approval. SimpleValueFact result = ruleEngineClient.ExecutePolicy <SimpleValueFact>("Contoso.Cloud.Integration.Demo.LoanPreapproval", loanApp); // Update the LoanPreapprovalReceived milestone. loanRequestActivity.LoanPreapprovalDecision = Convert.ToString(result.Value); loanRequestActivity.LoanPreapprovalReceived = DateTime.UtcNow; // Display pre-approval decision. SetResultDisplay(loanRequestActivity.LoanPreapprovalDecision); // Tells the event stream to invoke the UpdateActivity. trackingEventStream.UpdateActivity(loanRequestActivity); // Submit pre-approved loan for final processing. if (String.Compare(loanRequestActivity.LoanPreapprovalDecision, "Preapproved", true) == 0) { // Submit the loan application for processing (this will update LoanApplicationStarted, LoanFinalDecision and LoanFinalDecisionMade milestones. using (var loanProcessor = new ReliableServiceBusClient <ILoanApplicationProcessingServiceChannel>(roleConfig.GetServiceBusEndpoint("LoanApplication"), roleConfig.CommunicationRetryPolicy)) { loanProcessor.RetryPolicy.ExecuteAction(() => { loanProcessor.Client.Submit(loanApp); }); } } // Update the LoanFinalDecisionReceived milestone. loanRequestActivity.LoanFinalDecisionReceived = DateTime.UtcNow; // Tells the event stream to invoke the UpdateActivity and EndActivity operations. trackingEventStream.CompleteActivity(loanRequestActivity); }
/// <summary> /// Executes the specified BRE policy using zero or more facts. /// </summary> /// <typeparam name="T">The type of the result expected from the BRE policy.</typeparam> /// <param name="policyName">The name of the BRE policy that needs to be invoked.</param> /// <param name="facts">Zero or more facts that will be submitted to the policy for evaluation.</param> /// <returns>The instance of an object carrying the result of policy execution, or null reference if the policy was not fired successfully.</returns> public T ExecutePolicy <T>(string policyName, params object[] facts) where T : class, new() { Guard.ArgumentNotNullOrEmptyString(policyName, "policyName"); var callToken = TraceManager.WorkerRoleComponent.TraceIn(policyName); try { RulesEngineRequest request = new RulesEngineRequest(policyName); request.AddFacts(new T()); if (facts != null) { request.AddFacts(facts); } using (var rulesEngineClient = new ReliableServiceBusClient <IOnPremiseRulesEngineServiceChannel>(roleConfigExtension.OnPremiseRelayTwoWayEndpoint, roleConfigExtension.CommunicationRetryPolicy)) { RulesEngineResponse response = rulesEngineClient.RetryPolicy.ExecuteAction <RulesEngineResponse>(() => { return(rulesEngineClient.Client.ExecutePolicy(request)); }); if (response.Success) { return((from fact in response.Facts where fact.GetType() == typeof(T) select fact).FirstOrDefault() as T); } else { return(default(T)); } } } catch (Exception ex) { // Report on any exceptions and return the default value of T, do not re-throw the exception to the caller. TraceManager.WorkerRoleComponent.TraceError(ex); return(default(T)); } finally { TraceManager.WorkerRoleComponent.TraceOut(callToken); } }
public void Dispose(bool disposing) { if (!this.disposed) { if (disposing) { try { if (this.subscriber != null) { this.subscriber.Dispose(); this.subscriber = null; } } catch { // Do not let the code to fail on disposal. } try { if (this.publisher != null) { this.publisher.Dispose(); this.publisher = null; } } catch { // Do not let the code to fail on disposal. } this.disposed = true; } } }
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); } }
/// <summary> /// Applies the specified transformation map against the input document. /// </summary> /// <param name="transformName">Either partial or fully qualified name of the transformation map.</param> /// <param name="input">The input document that needs to be transformed.</param> /// <returns>The results from transformation.</returns> public XDocument ApplyTransform(string transformName, XDocument input) { Guard.ArgumentNotNull(this.roleConfigExtension, "roleConfigExtension"); Guard.ArgumentNotNullOrEmptyString(transformName, "transformName"); Guard.ArgumentNotNull(input, "input"); Guard.ArgumentNotNull(input.Root, "input.Root"); var callToken = TraceManager.WorkerRoleComponent.TraceIn(transformName, input.Root.Name); try { ServiceBusEndpointInfo sbEndpointInfo = this.roleConfigExtension.GetServiceBusEndpoint(WellKnownEndpointName.ScalableTransformService); if (sbEndpointInfo != null) { using (ReliableServiceBusClient <IScalableTransformationServiceChannel> transform = new ReliableServiceBusClient <IScalableTransformationServiceChannel>(sbEndpointInfo, this.roleConfigExtension.CommunicationRetryPolicy)) using (MemoryStream dataStream = new MemoryStream()) using (XmlWriter xmlWriter = XmlWriter.Create(dataStream)) { input.WriteTo(xmlWriter); xmlWriter.Flush(); dataStream.Seek(0, SeekOrigin.Begin); XslTransformState preparedState = transform.RetryPolicy.ExecuteAction <XslTransformState>(() => { return(transform.Client.PrepareTransform(dataStream)); }); XslTransformState transformedState = transform.RetryPolicy.ExecuteAction <XslTransformState>(() => { return(transform.Client.ApplyTransform(transformName, preparedState)); }); using (Stream transformedData = transform.RetryPolicy.ExecuteAction <Stream>(() => { return(transform.Client.CompleteTransform(transformedState)); })) { return(XDocument.Load(transformedData)); } } } else { throw new CloudApplicationException(String.Format(CultureInfo.CurrentCulture, ExceptionMessages.ServiceBusEndpointNotFound, WellKnownEndpointName.ScalableTransformService)); } } catch (Exception ex) { TraceManager.WorkerRoleComponent.TraceError(ex, callToken); throw; } finally { TraceManager.WorkerRoleComponent.TraceOut(callToken); } }
/// <summary> /// Returns the XSLT transformation metadata for the specified transform object name. /// </summary> /// <param name="transformName">Either partial or fully qualified name of the transformation object.</param> /// <returns>A set of metadata for the XSLT-based transformation object.</returns> public XslTransformMetadata GetXslTransformMetadata(string transformName) { var callToken = TraceManager.WorkerRoleComponent.TraceIn(transformName); try { using (ReliableServiceBusClient <IOnPremiseTransformationServiceChannel> transformServiceClient = new ReliableServiceBusClient <IOnPremiseTransformationServiceChannel>(this.roleConfigExtension.OnPremiseRelayTwoWayEndpoint, this.roleConfigExtension.CommunicationRetryPolicy)) { return(transformServiceClient.RetryPolicy.ExecuteAction <XslTransformMetadata>(() => { return transformServiceClient.Client.GetXslTransformMetadata(transformName); })); } } finally { TraceManager.WorkerRoleComponent.TraceOut(callToken); } }
/// <summary> /// Initializes a new instance of the trace listener using the specified configuration settings. /// </summary> /// <param name="diagnosticServiceEndpoint">The name of the Service Bus endpoint definition that corresponds to the on-premises hosted diagnostic service.</param> /// <param name="diagnosticStorageAccount">The name of the storage account in which diagnostic data will be queued before relayed to the on-premises hosted diagnostic service.</param> /// <param name="inMemoryQueueCapacity">The maximum capacity of the non-durable in-memory queue in which trace events are being stored before they are persisted into an Azure queue.</param> /// <param name="inMemoryQueueListenerSleepTimeout">The interval in milliseconds during which a dequeue thread is waiting for new events in the in-memory queue.</param> /// <param name="diagQueueEventBatchSize">The maximum number of trace events in a batch that is submitted to the on-premises hosted diagnostic service.</param> /// <param name="diagQueueListenerSleepTimeout">The interval in milliseconds during which a dequeue thread is waiting for new events to be deposited into the Azure queue.</param> public OnPremisesBufferedTraceListener(string diagnosticServiceEndpoint, string diagnosticStorageAccount, int inMemoryQueueCapacity, int inMemoryQueueListenerSleepTimeout, int diagQueueEventBatchSize, int diagQueueListenerSleepTimeout) { Guard.ArgumentNotNullOrEmptyString(diagnosticServiceEndpoint, "diagnosticServiceEndpoint"); Guard.ArgumentNotZeroOrNegativeValue(inMemoryQueueCapacity, "inMemoryQueueCapacity"); Guard.ArgumentNotZeroOrNegativeValue(inMemoryQueueListenerSleepTimeout, "inMemoryQueueListenerSleepTimeout"); Guard.ArgumentNotZeroOrNegativeValue(diagQueueEventBatchSize, "diagQueueEventBatchSize"); Guard.ArgumentNotZeroOrNegativeValue(diagQueueListenerSleepTimeout, "diagQueueListenerSleepTimeout"); // Configure the general properties of the trace listener. Name = ListenerName; NeedIndent = false; // Configure the in-memory queue and its parameters, set up a backup trace listener. this.inMemoryQueue = new ConcurrentQueue <TraceEventRecord>(); this.inMemoryQueueCapacity = inMemoryQueueCapacity; this.inMemoryQueueListenerSleepTimeout = inMemoryQueueListenerSleepTimeout; this.diagQueueEventBatchSize = diagQueueEventBatchSize; this.diagQueueListenerSleepTimeout = diagQueueListenerSleepTimeout; this.diagQueueName = GetServiceBusQueueName(CloudEnvironment.CurrentRoleInstanceId); this.backupTraceListener = new CloudDiagnosticTraceListener(); // Configure Service Bus endpoint for the Diagnostic Service. ServiceBusEndpointInfo diagServiceEndpointInfo = ApplicationConfiguration.Current.ServiceBusSettings.Endpoints[diagnosticServiceEndpoint]; // Validate Service Bus endpoints. if (null == diagServiceEndpointInfo) { throw new ConfigurationErrorsException(String.Format(CultureInfo.CurrentCulture, ExceptionMessages.SpecifiedServiceBusEndpointNotFound, diagnosticServiceEndpoint, ServiceBusConfigurationSettings.SectionName)); } // Retrieve the storage account settings from application configuration. StorageAccountConfigurationSettings storageSettings = ApplicationConfiguration.Current.GetConfigurationSection <StorageAccountConfigurationSettings>(StorageAccountConfigurationSettings.SectionName); // Validate the presence of storage account settings. if (null == storageSettings) { throw new ConfigurationErrorsException(String.Format(CultureInfo.CurrentCulture, ExceptionMessages.ConfigSectionNotFoundInConfigSource, StorageAccountConfigurationSettings.SectionName)); } // Determine the storage account for storing tracing data. By default, assume that storage account is defined in the trace listener configuration. string diagStorageAccountName = diagnosticStorageAccount; // If storage account is not defined in the trace listener configuration, switch to the storage account specified in the Application Diagnostic Settings section. if (String.IsNullOrEmpty(diagStorageAccountName)) { // Retrieve the diagnostic settings from application configuration. ApplicationDiagnosticSettings diagSettings = ApplicationConfiguration.Current.GetConfigurationSection <ApplicationDiagnosticSettings>(ApplicationDiagnosticSettings.SectionName); // Validate the presence of diagnostic settings. if (null == diagSettings) { throw new ConfigurationErrorsException(String.Format(CultureInfo.CurrentCulture, ExceptionMessages.ConfigSectionNotFoundInConfigSource, ApplicationDiagnosticSettings.SectionName)); } diagStorageAccountName = diagSettings.DiagnosticStorageAccount; } // Resolve the storage account details based on the account name defined in the diagnostic settings . StorageAccountInfo diagStorageAccount = storageSettings.Accounts.Get(diagStorageAccountName); // Validate storage account details. if (null == diagStorageAccount) { throw new ConfigurationErrorsException(String.Format(CultureInfo.CurrentCulture, ExceptionMessages.StorageAccountNotFoundInConfigSource, diagStorageAccountName)); } // Configure retry policies. this.sbRetryPolicy = new RetryPolicy <ServiceBusTransientErrorDetectionStrategy>(DefaultRetryCount); this.queueRetryPolicy = new RetryPolicy <StorageTransientErrorDetectionStrategy>(DefaultRetryCount); this.sbRetryPolicy.RetryOccurred += HandleServiceBusEndpointRetryState; this.queueRetryPolicy.RetryOccurred += HandleCloudQueueRetryState; // Configure Service Bus and Message Queue clients. this.diagnosticService = new ReliableServiceBusClient <IDiagnosticLoggingServiceChannel>(diagServiceEndpointInfo, this.sbRetryPolicy); this.diagQueueStorage = new ReliableCloudQueueStorage(diagStorageAccount, this.queueRetryPolicy); this.diagQueueReaderDone = new ManualResetEvent(false); this.diagQueueWriterDone = new ManualResetEvent(false); // Ensure that destination cloud queue exists, create if necessary. this.diagQueueStorage.CreateQueue(this.diagQueueName); // Enable background listeners to run. this.isRunning = true; StartInMemoryQueueListener(); StartServiceBusQueueListener(); }