public string DispatchStateListenerResponse(IAuthenticatedWho authenticatedWho, string callbackUri, ListenerServiceResponseAPI listenerServiceResponse) { HttpClient httpClient = null; HttpContent httpContent = null; HttpResponseMessage httpResponseMessage = null; string invokeResponse = null; Policy.Handle <ServiceProblemException>().Retry(HttpUtils.MAXIMUM_RETRIES).Execute(() => { using (httpClient = HttpUtils.CreateHttpClient(authenticatedWho, authenticatedWho.ManyWhoTenantId.ToString(), null)) { // Use the JSON formatter to create the content of the request body httpContent = new StringContent(JsonConvert.SerializeObject(listenerServiceResponse)); httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json"); // Post the authentication request over to ManyWho httpResponseMessage = httpClient.PostAsync(callbackUri, httpContent).Result; // Check the status of the response and respond appropriately if (httpResponseMessage.IsSuccessStatusCode) { invokeResponse = JsonConvert.DeserializeObject <string>(httpResponseMessage.Content.ReadAsStringAsync().Result); } else { throw new ServiceProblemException(new ServiceProblem(callbackUri, httpResponseMessage, string.Empty)); } } }); return(invokeResponse); }
private void Execute(INotifier notifier, String tenantId, String mode, WorkflowRuleNotification workflowRuleNotification) { Dictionary <String, ListenerServiceRequestAPI> salesforceListenerEntries = null; ListenerServiceResponseAPI listenerServiceResponse = null; ListenerServiceRequestAPI listenerServiceRequest = null; SforceService sforceService = null; String authenticationStrategy = null; String authenticationUrl = null; String securityToken = null; String invokeType = null; String username = null; String password = null; if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("Executing listener notification."); } // Go through each object identifier in the notification if (workflowRuleNotification.ObjectIDs != null && workflowRuleNotification.ObjectIDs.Count > 0) { if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("Workflow event has object identifiers."); } foreach (String objectId in workflowRuleNotification.ObjectIDs) { if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("Processing object identifier: " + objectId); } // Check to see if ManyWho has asked us to listen to any of them salesforceListenerEntries = SalesforceListenerSingleton.GetInstance().GetListenerRequests(tenantId, objectId); // Check to see if we're actually listening if (salesforceListenerEntries != null && salesforceListenerEntries.Count > 0) { if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("Object has listener entries."); } // If it has, send a listen notification back to the workflow engine - one by one at the moment (no bulk!) foreach (KeyValuePair <String, ListenerServiceRequestAPI> pair in salesforceListenerEntries) { // Get the listener request out listenerServiceRequest = pair.Value; if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("Executing listener entry."); } // Create the service response listenerServiceResponse = new ListenerServiceResponseAPI(); listenerServiceResponse.annotations = listenerServiceRequest.annotations; listenerServiceResponse.culture = listenerServiceRequest.culture; listenerServiceResponse.tenantId = listenerServiceRequest.tenantId; listenerServiceResponse.token = listenerServiceRequest.token; // Apply the settings for the response from the request so the engine has the full details about the object listenerServiceResponse.listeningEventValue = listenerServiceRequest.valueForListening; listenerServiceResponse.listeningEventValue.contentType = listenerServiceRequest.valueForListening.contentType; listenerServiceResponse.listeningEventValue.contentValue = listenerServiceRequest.valueForListening.contentValue; listenerServiceResponse.listeningEventValue.developerName = listenerServiceRequest.valueForListening.developerName; listenerServiceResponse.listeningEventValue.typeElementDeveloperName = listenerServiceRequest.valueForListening.typeElementDeveloperName; listenerServiceResponse.listeningEventValue.typeElementId = listenerServiceRequest.valueForListening.typeElementId; listenerServiceResponse.listeningEventValue.typeElementPropertyDeveloperName = listenerServiceRequest.valueForListening.typeElementPropertyDeveloperName; listenerServiceResponse.listeningEventValue.typeElementPropertyId = listenerServiceRequest.valueForListening.typeElementPropertyId; listenerServiceResponse.listeningEventValue.valueElementId = listenerServiceRequest.valueForListening.valueElementId; // Get the configuration values out that are needed to check the voting status // TODO: we should smart cache the login info and connection authenticationUrl = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_VALUE_AUTHENTICATION_URL, listenerServiceRequest.configurationValues, true); username = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_VALUE_USERNAME, listenerServiceRequest.configurationValues, true); password = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_VALUE_PASSWORD, listenerServiceRequest.configurationValues, true); securityToken = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_VALUE_SECURITY_TOKEN, listenerServiceRequest.configurationValues, false); authenticationStrategy = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_VALUE_AUTHENTICATION_STRATEGY, listenerServiceRequest.configurationValues, false); if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("Logging into salesforce using: " + username); } if (String.IsNullOrWhiteSpace(authenticationStrategy) == true || authenticationStrategy.Equals(SalesforceServiceSingleton.AUTHENTICATION_STRATEGY_STANDARD, StringComparison.OrdinalIgnoreCase) == true || authenticationStrategy.Equals(SalesforceServiceSingleton.AUTHENTICATION_STRATEGY_ACTIVE_USER, StringComparison.OrdinalIgnoreCase) == true) { sforceService = SalesforceDataSingleton.GetInstance().LogUserInBasedOnSession(listenerServiceRequest.configurationValues, workflowRuleNotification.SessionID, workflowRuleNotification.SessionURL); } else if (authenticationStrategy.Equals(SalesforceServiceSingleton.AUTHENTICATION_STRATEGY_SUPER_USER, StringComparison.OrdinalIgnoreCase) == true) { // Login to salesforce using the details in the service request sforceService = SalesforceDataSingleton.GetInstance().LoginUsingCredentials(authenticationUrl, username, password, securityToken); } else { throw new ArgumentNullException("ConfigurationValues", String.Format("The provided authentication strategy is not supported: '{0}'", authenticationStrategy)); } if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("Getting full sObject for: " + objectId); } // Load the latest object from salesforce so we have the data to send back listenerServiceResponse.listeningEventValue.objectData = SalesforceDataSingleton.GetInstance().LoadSObjectByIdentifier(sforceService, workflowRuleNotification.ObjectName, objectId, true); try { if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("Executing event against ManyWho"); } // Dispatch a listen response to the engine as an event has occurred invokeType = RunSingleton.GetInstance().Event(notifier, null, tenantId, listenerServiceRequest.callbackUri, listenerServiceResponse); } catch (Exception exception) { if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("Event execution failed with: " + BaseHttpUtils.GetExceptionMessage(exception)); } // Something went wrong - but we ignore it for now invokeType = ManyWhoConstants.INVOKE_TYPE_FORWARD; } if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("Service returned invoke type of: " + invokeType); } // If the engine returns nothing, errors or returns an response other than a "WAIT", we delete the listener for now // TODO: make this a bit more intelligent so we can handle things like retry if (String.IsNullOrWhiteSpace(invokeType) == false && invokeType.IndexOf(ManyWhoConstants.INVOKE_TYPE_WAIT, StringComparison.InvariantCultureIgnoreCase) < 0) { if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("Removing entry from listeners for invoke type: " + invokeType); } SalesforceListenerSingleton.GetInstance().UnregisterListener(tenantId, objectId, listenerServiceRequest); } } } } } }