/// <summary> /// Alert an exception to Slack /// </summary> /// <param name="message"></param> /// <param name="ex"></param> /// <param name="logTrace"></param> private void AlertErrorToSlack(object message, Exception ex, ILogTrace logTrace) { // don't alert to Slack if (!SlackAlertEnabled || string.IsNullOrWhiteSpace(SlackAlertChannel)) { return; } // alert to Slack on background var slackMsg = new SlackMessage { Channel = SlackAlertChannel, Username = $"MessageHandler:{Handler.GetType().Name}", Texts = new List <string> { "```", $"Failed to process message. Error: {ex.Message}", JsonConvert.SerializeObject(message, Formatting.Indented), $"StackTrace: {ex.StackTrace}", "```" } }; Task.WaitAll(SvcSlack.SendWithErrorHandler(slackMsg, logTrace)); }
/// <summary>Gets all salesforce objects asynchronous.</summary> /// <typeparam name="T"></typeparam> /// <param name="partyId">The party identifier.</param> /// <param name="getFirstPageFunc">The get first page function.</param> /// <param name="svcSalesforce">The SVC salesforce.</param> /// <param name="oauthTokenManager">The oauth token manager.</param> /// <param name="logTrace">The log trace.</param> /// <returns></returns> public static async Task <IList <T> > GetAllSalesforceObjectsAsync <T>(int partyId, Func <Task <ResponseBase <SalesforceQueryResponseData <T>, IList <SalesforceError> > > > getFirstPageFunc, ISalesforceServiceClientV2 svcSalesforce, IOAuthTokenManager oauthTokenManager, ILogTrace logTrace) { var startedAt = DateTime.UtcNow; // send request to get the first batch from Salesforce var firstTopicsRes = await GetFirstSalesforceObjectPageAsync(partyId, getFirstPageFunc, svcSalesforce, oauthTokenManager, logTrace); var sfObjects = firstTopicsRes.Data.Records; // repeat until all the topics are retrieved, just in case, usually there won't be more than 1000 topics var nextRecordUrl = firstTopicsRes.Data.NextRecordsUrl; while (nextRecordUrl != null) { var nextTopicsRes = await svcSalesforce.GetNextPageAsync(firstTopicsRes.Data); nextRecordUrl = nextTopicsRes.Data.NextRecordsUrl; sfObjects = sfObjects.Concat(nextTopicsRes.Data.Records).ToList(); } logTrace?.Add(LogLevel.Info, $"GetAllSalesforce{typeof(T).Name}Async() - Done", $"{typeof(T).Name}s #{sfObjects.Count}", startedAt); return(sfObjects.ToList()); }
public override async Task <IList <TMessage> > ParseMessages(object reqData, ILogTrace logTrace) { var strMessage = JsonConvert.SerializeObject(reqData); logTrace?.Add(LogLevel.Debug, "ParseMessages()", new { strMessage }); var sqsEvent = JsonConvert.DeserializeObject <SQSEvent>(strMessage); logTrace?.Add(LogLevel.Info, "ParseMessages()", "Parsed SQSEvent"); return(ParseMessages(sqsEvent)); }
protected async Task DeleteGroupsAsync( int partyId, IList <SalesforceTopicMapping> salesforceTopicMappings, IList <SalesforceTopicMapping> remoteTopicMappings, IList <string> userSelectedGroupIds, ILogTrace logTrace) { var startedAt = DateTime.UtcNow; // deleted groups are the ones that currently is in the database but not in the remote list var deletedGroups = remoteTopicMappings.Except(salesforceTopicMappings, AppStore.SalesforceTopicMappingComparer); // if user selected to sync only some groups, also delete the groups that is not in this list if (userSelectedGroupIds.Any()) { var userSelectedGroups = userSelectedGroupIds.Select( groupId => new SalesforceTopicMapping { SalesforceTopicId = groupId } ).ToList(); var unselectedGroups = remoteTopicMappings.Except(userSelectedGroups, AppStore.SalesforceTopicMappingComparer); deletedGroups = deletedGroups.Concat(unselectedGroups).ToList(); } // delete the FMG Groups first var groupIds = deletedGroups.Select(group => group.FMGGroupId).Distinct().ToList(); var groupTasks = groupIds.Select(groupId => AppStore.ContactsServiceClient.DeleteGroupAsync( new DeleteGroupRequest { GroupID = groupId }, logTrace )).ToList(); await Task.WhenAll(groupTasks); // delete the RemoteGroupMapping after deleting the FMG Groups because the GroupMapping objects hold the // FMG Group ids var remoteGroupIds = deletedGroups.Select(group => group.SalesforceTopicId).Distinct().ToList(); var groupMappingTasks = remoteGroupIds.Select(remoteGroupId => AppStore.RemoteDataServiceClient.DeleteRemoteGroupMappingAsync( new DeleteRemoteGroupMappingRequestData { PartyId = partyId, RemoteGroupId = remoteGroupId }, logTrace )).ToList(); await Task.WhenAll(groupMappingTasks); // log logTrace?.Add(LogLevel.Info, "DeleteGroupsAsync", $"{groupIds.Count()} deleted", startedAt); }
protected async Task InsertNewGroupsAsync(int partyId, IList <SalesforceTopicMapping> salesforceTopicMappings, IList <SalesforceTopicMapping> remoteTopicMappings, IList <string> filteredRemoteGroupIds, ILogTrace logTrace) { var startedAt = DateTime.UtcNow; // logging logTrace?.Add(LogLevel.Debug, "salesforceTopicTopicMappings", salesforceTopicMappings .Select(topic => new { topic.SalesforceTopicId, topic.SalesforceTopicName }) .ToList()); // find the new topics var newTopicMappings = salesforceTopicMappings.Except(remoteTopicMappings, AppStore.SalesforceTopicMappingComparer).ToList(); logTrace?.Add(LogLevel.Debug, "newtopicMappings", newTopicMappings.Select(topic => new { topic.SalesforceTopicId, topic.SalesforceTopicName }).ToList()); if (filteredRemoteGroupIds.Any()) { var filteredTopicMappings = filteredRemoteGroupIds.Select( remoteGroupId => new SalesforceTopicMapping { SalesforceTopicId = remoteGroupId }); newTopicMappings = newTopicMappings.Intersect(filteredTopicMappings, AppStore.SalesforceTopicMappingComparer).ToList(); logTrace?.Add(LogLevel.Debug, "newtopicMappings after intersect", newTopicMappings.Select(topic => new { topic.SalesforceTopicId, topic.SalesforceTopicName }) .ToList()); } // logging logTrace?.Add( LogLevel.Info, "New Groups", newTopicMappings.Select(topic => topic.SalesforceTopicName).ToList() ); // insert these as FMGGroups var tasks = newTopicMappings.Select(newTopic => InsertNewGroupAsync(partyId, newTopic, logTrace)).ToList(); await Task.WhenAll(tasks); // log logTrace?.Add( LogLevel.Info, "InsertNewGroupsAsync", $"{newTopicMappings.Count()} new groups inserted", startedAt ); }
/// <summary> /// Processes the message and send next messages if any /// </summary> /// <returns>The message async.</returns> /// <param name="message">Message.</param> /// <param name="logTrace">Log trace.</param> async Task ProcessMessageAsync(TMessage message, ILogTrace logTrace) { // for debugging if failed to process the message logTrace?.Add(LogLevel.Debug, "ProcessMessageAsync()", new { message }); // process message based on business logic var nextMessages = await Handler.ProcessAsync(message, logTrace); // publish next messages to bus // (delegate next logic into another async workers) if (nextMessages != null && nextMessages.Any()) { await SvcServiceBus.PublishMessages(nextMessages, logTrace); } }
/// <summary> /// Get all Topics from Salesforce, convert to SalesforceTopicMapping schema before returning /// </summary> /// <param name="svcSalesforce"></param> /// <param name="logTrace"></param> /// <returns> /// The list of SalesforceTopicMapping objects representing the current Topics in Salesforce /// All the FMGGroupId props of these objects will be null /// </returns> protected async Task <IList <SalesforceTopicMapping> > GetAllSalesforceTopicsAsync( int partyId, ISalesforceServiceClientV2 svcSalesforce, ILogTrace logTrace) { var topics = await SalesforceUtil.GetAllSalesforceObjectsAsync(partyId, () => svcSalesforce.GetAllTopicsAsync(), svcSalesforce, AppStore.OAuthTokenManager, logTrace); // map the result to the SalesforceTopicMapping object var groupMappings = topics.Select(topic => new SalesforceTopicMapping { SalesforceTopicId = topic.Id, SalesforceTopicName = topic.Name }); return(groupMappings.ToList()); }
/// <summary> /// Processes the async. /// </summary> /// <returns>The async.</returns> /// <param name="message">Message.</param> /// <param name="logTrace">Log trace.</param> public override async Task <IEnumerable <IMessage> > ProcessAsync (SalesforceContactsSyncerMessage message, ILogTrace logTrace) { var partyId = message.PartyId; // get the sync setting first var syncSetting = await GetSyncSettingAsync(partyId, logTrace); // init the salesforce client var svcSalesforce = InitSalesforceServiceClientAsync(syncSetting.OAuthToken, logTrace); var getContactsData = new SalesforceQueryResponseData <Contact>(); var isFullSync = !(syncSetting.RemoteGroupIDs?.Count > 0); // get remote contact ids belong at least 1 group. // remoteContactIdsBelongGroup is empty that mean FULL SYNC var remoteContactIdsBelongGroup = new Dictionary <string, bool>(); if (!isFullSync) { remoteContactIdsBelongGroup = await GetRemoteContactIdsBelongGroupAsync(partyId, logTrace); } // 1. Get contacts from Salesforce // 2. Publish each contact pages for FMGContactUpdater do { // get first page, write total contact to Redis. if (string.IsNullOrWhiteSpace(getContactsData.NextRecordsUrl)) { getContactsData = await GetContacts(partyId, svcSalesforce, syncSetting, logTrace); // write total contact to redis. await WriteTotalContactToRedis(partyId, getContactsData.TotalSize, logTrace); } else { getContactsData = await GetContactsNextPage(svcSalesforce, getContactsData, logTrace); } await PublishToFmgContactUpdater(syncSetting, getContactsData?.Records, remoteContactIdsBelongGroup, isFullSync, logTrace); } while (!string.IsNullOrWhiteSpace(getContactsData.NextRecordsUrl)); return(null); }
/// <summary> /// /// </summary> /// <param name="partyId"></param> /// <param name="logTrace"></param> /// <returns></returns> protected async Task <IList <SalesforceTopicMapping> > GetAllRemoteGroupMappingsAsync( int partyId, ILogTrace logTrace) { // send request to get all the RemoteGroupMapping var remoteGroupMappingRes = await AppStore.RemoteDataServiceClient.GetAllRemoteGroupMappingsAsync( new GetAllRemoteGroupMappingsRequestData { PartyId = partyId }, logTrace ); // map to SalesforceTopicMapping schema var res = remoteGroupMappingRes.Data.RemoteGroupMappings.Select(groupMapping => new SalesforceTopicMapping { SalesforceTopicId = groupMapping.RemoteGroupId, SalesforceTopicName = groupMapping.RemoteGroupName, FMGGroupId = groupMapping.GroupId }).ToList(); logTrace.Add(LogLevel.Info, "GetAllRemoteGroupMappingsAsync", $"# GroupMapping: {res.Count}"); return(res); }
/// <summary> /// Check the ApproximateReceiveCount with MaximumRetryCount /// </summary> /// <param name="message"></param> /// <param name="reqData"></param> /// <param name="logTrace"></param> /// <returns></returns> private bool IsAlertToSlack(TMessage message, object reqData, ILogTrace logTrace) { // alert to Slack if there is no config for SQS Maximum Retry. if (SqsMaximumReceives == null) { return(true); } try { var sqsEvent = JsonConvert.DeserializeObject <SQSEvent>(JsonConvert.SerializeObject(reqData)); // Find the SQS message body have same message id that we generated for a message. var sqsMessage = sqsEvent.Records.FirstOrDefault(x => JsonConvert.DeserializeObject <TMessage>(x.Body).MessageId.Equals(message.MessageId)); var isApproximateReceiveCount = sqsMessage.Attributes.TryGetValue("ApproximateReceiveCount", out string approximateReceiveCount); logTrace.ExtendProps(new Dictionary <string, object> { { "approximateReceiveCount", approximateReceiveCount } }); // Check the ApproximateReceiveCount of message. if (sqsMessage != null && isApproximateReceiveCount && int.Parse(approximateReceiveCount) == SqsMaximumReceives) { return(true); } return(false); } catch (Exception ex) { logTrace.Add(LogLevel.Warning, "IsAlertToSlack()", new { ex.Message, ex.StackTrace }); // Alert to Slack if have any exception when check the ApproximateReceiveCount. return(true); } }
public TestServiceA(ILogTrace logTrace) { _logTrace = logTrace; }
public TestService(ILogTrace logTrace, ITestServiceA serviceA) { _logTrace = logTrace; _serviceA = serviceA; }
public RequestBuilder(ILogTrace logTrace) { _logTrace = logTrace; }
/// <summary> /// Update group names for the groups that remain from last sync /// </summary> /// <param name="partyId"></param> /// <param name="salesforceTopicMappings"></param> /// <param name="remoteTopicMappings"></param> /// <param name="logTrace"></param> /// <returns></returns> protected async Task UpdateGroupNames(int partyId, IList <SalesforceTopicMapping> salesforceTopicMappings, IList <SalesforceTopicMapping> remoteTopicMappings, IList <string> userSelectedGroupIds, ILogTrace logTrace) { var startedAt = DateTime.UtcNow; // find the groups that remain from last sync // Cannot use IList.Intersection because the salesforceTopicMapping items don't contain // the FMGGroupId while the remoteTopicMappings items don't contain the new name from Salesforce var remainGroups = new List <SalesforceTopicMapping>(); foreach (var remoteTopicMapping in remoteTopicMappings) { // var salesforceTopicMapping = salesforceTopicMappings.FirstOrDefault(item => item.SalesforceTopicId == remoteTopicMapping.SalesforceTopicId); if (salesforceTopicMapping == null) { continue; } salesforceTopicMapping.FMGGroupId = remoteTopicMapping.FMGGroupId; remainGroups.Add(salesforceTopicMapping); } // is user selected to sync only some groups, filter to those groups only if (userSelectedGroupIds.Any()) { var userSelectedGroups = userSelectedGroupIds.Select( groupId => new SalesforceTopicMapping { SalesforceTopicId = groupId } ).ToList(); remainGroups = remainGroups.Intersect(userSelectedGroups, AppStore.SalesforceTopicMappingComparer) .ToList(); } // update FMG Group var groupTasks = remainGroups.Select(group => AppStore.ContactsServiceClient.UpdateGroupAsync( new UpdateGroupRequest { GroupID = group.FMGGroupId, Name = group.SalesforceTopicName } )).ToList(); foreach (var task in groupTasks) { await task; } logTrace.Add(LogLevel.Info, "Update FMG Groups", $"{groupTasks.Count()} updated", startedAt); // update RemoteGroupMapping startedAt = DateTime.UtcNow; var remoteTasks = remainGroups.Select(group => AppStore.RemoteDataServiceClient.UpsertRemoteGroupMappingAsync( new UpsertRemoteGroupMappingRequestData { GroupId = group.FMGGroupId, PartyId = partyId, RemoteGroupId = group.SalesforceTopicId, RemoteGroupName = group.SalesforceTopicName }, logTrace )).ToList(); foreach (var task in remoteTasks) { await task; } logTrace.Add(LogLevel.Info, "Update RemoteGroupMapping", $"{remoteTasks.Count()} updated", startedAt); }
/// <inheritdoc /> public override async Task <IEnumerable <IMessage> > ProcessAsync(SalesforceTopicsSyncerMessage message, ILogTrace logTrace) { var partyId = message.PartyId; // get the sync setting first var syncSetting = await VerifySyncStatusAsync(partyId, logTrace); var isSyncAll = syncSetting.IsSyncAll; var isFullSync = syncSetting.IsFullSync; logTrace?.Add(LogLevel.Info, "Sync Setting", new { isSyncAll, isFullSync }); // init the salesforce client var svcSalesforce = InitSalesforceServiceClientAsync(syncSetting.OAuthToken, logTrace); // get the list of SalesforceCampaigns and RemoteGroupMapping // these 2 methods both return a list of SalesforceTopicMapping so we can compare those 2 and do some // operations like Intersection, Difference,... // NOTE: Initially, we support Salesforce Topics as Groups so these methods all return // SalesforceTopicMapping. However, we changed to support Salesforce Campaigns as Groups later. We didn't // want to change a lot of code here so we just changes the getSFGroupMappingFunc to get the Salesforce // Campaigns instead of the Topics but it still returns the Topic schema. var isSyncCampaign = true; Func <Task <IList <SalesforceTopicMapping> > > getSFGroupMappingFunc = () => GetAllSalesforceTopicsAsync(partyId, svcSalesforce, logTrace); if (isSyncCampaign) { if (syncSetting.IntegrationType == CRMIntegrationTypes.Practifi) { getSFGroupMappingFunc = () => GetAllPractifiCampaignsAsync(partyId, svcSalesforce, logTrace); } else { getSFGroupMappingFunc = () => GetAllSalesforceCampaignsAsync(partyId, svcSalesforce, logTrace); } } var groupMappingResults = await Task.WhenAll(getSFGroupMappingFunc(), GetAllRemoteGroupMappingsAsync(partyId, logTrace)); // the TopicMappings from Salesforce, these objects don't have the FMGGroupId prop var salesforceTopicMappings = groupMappingResults.ElementAt(0); // the TopicMappings retrieved from RemoteData service, these objects have the linked FMGGroupId prop var remoteTopicMappings = groupMappingResults.ElementAt(1); // the list of GroupIds that user selected on UI var userSelectedGroupIds = syncSetting.RemoteGroupIDs ?? new List <string>(); // add new groups await InsertNewGroupsAsync( partyId, salesforceTopicMappings, remoteTopicMappings, userSelectedGroupIds, logTrace ); // delete non-existing groups await DeleteGroupsAsync(partyId, salesforceTopicMappings, remoteTopicMappings, userSelectedGroupIds, logTrace); // update the names for all the groups that remain from the sync await UpdateGroupNames(partyId, salesforceTopicMappings, remoteTopicMappings, userSelectedGroupIds, logTrace); return(new List <SalesforceTopicAssignmentsSyncerMessage> { new SalesforceTopicAssignmentsSyncerMessage { PartyId = partyId } }); }
public TestClientA(HttpClient httpClient, ILogTrace logTrace, Func <IRequestBuilder> requestBuilder) { _httpClient = httpClient; _logTrace = logTrace; _requestBuilder = requestBuilder; }
/// <summary> /// Parse message object send from APIGateway/SNS Topic to messages to handle. /// </summary> /// <returns>The messages.</returns> /// <param name="reqData">The lambda request data event object</param> /// <param name="logTrace">Log trace.</param> public abstract Task <IList <TMessage> > ParseMessages(object reqData, ILogTrace logTrace);
GetFirstSalesforceObjectPageAsync <T>(int partyId, Func <Task <ResponseBase <SalesforceQueryResponseData <T>, IList <SalesforceError> > > > getFirstPageFunc, ISalesforceServiceClientV2 svcSalesforce, IOAuthTokenManager oauthTokenManager, ILogTrace logTrace) { var domain = $"GetFirstSalesforce{typeof(T).Name}Page"; var startedAt = DateTime.UtcNow; // send request to get the first batch from Salesforce var res = await getFirstPageFunc(); logTrace?.Add(LogLevel.Info, domain, "First try", startedAt); // success case if (res.Status == HttpStatusCode.OK) { return(res); } // error case var errorCode = res.Error?.FirstOrDefault()?.ErrorCode; if (errorCode == null) { throw new Exception($"{domain} - Status {res.Status} - Message {res.ErrorString}"); } if (errorCode != "INVALID_SESSION_ID") { throw new Exception( $"{domain} - Status {res.Status} - Code {errorCode} - Message {res.ErrorString}" ); } logTrace?.Add(LogLevel.Info, domain, "AccessToken expired"); // try to refresh token startedAt = DateTime.UtcNow; var oauthToken = await oauthTokenManager.RefreshAccessTokenAsync <SalesforceOAuthError>( new RefreshAccessTokenRequest { PartyId = partyId, MaxRetries = 5, RetryWaitSecondsIfFailed = 5 }, logTrace); if (oauthToken == null) { logTrace?.Add(LogLevel.Warning, domain, "Refresh Token Failed.", startedAt); throw new IgnoreProcessingMessageException("Refresh Token Failed.", $"Failed to RefreshAccessToken for partyId = {partyId}"); } logTrace?.Add(LogLevel.Info, domain, "AccessToken refreshed", startedAt); // update the access token in svcSalesforce svcSalesforce.AccessToken = oauthToken.AccessToken; // try again startedAt = DateTime.UtcNow; res = await getFirstPageFunc(); logTrace?.Add(LogLevel.Info, domain, "Task retried", startedAt); // success case if (res.Status == HttpStatusCode.OK) { return(res); } // error case throw new Exception($"{domain} - Status {res.Status} - Code {errorCode} - Message {res.ErrorString}"); }
/// <summary> /// Writes the total contact to redis. /// This work is used to prepare for update sync status when sync process finished. /// </summary> /// <param name="partyId">The party identifier.</param> /// <param name="totalContact">The total contact.</param> /// <param name="logTrace">The log trace.</param> async Task WriteTotalContactToRedis(int partyId, int totalContact, ILogTrace logTrace) {
/// <summary> /// Init the Salesforce service client for this PartyId by getting the APIEndpoint and AccessToken from the /// OAuthToken service /// </summary> /// <param name="token"></param> /// <param name="logTrace"></param> /// <returns></returns> protected virtual ISalesforceServiceClientV2 InitSalesforceServiceClientAsync( OAuthTokenSyncSetting accessToken, ILogTrace logTrace) { return(SalesforceServiceClientV2Factory.Create(accessToken.APIEndpoint, accessToken.AccessToken)); }
/// <summary> /// Processes the async. /// </summary> /// <returns>The async.</returns> /// <param name="message">Message.</param> /// <param name="logTrace">Log trace.</param> public abstract Task <IEnumerable <IMessage> > ProcessAsync(TMessage message, ILogTrace logTrace);
public TestHttpClientHandler(ILogTrace logTrace) { _logTrace = logTrace; }
/// <summary> /// Insert 1 single FMGGroup + RemoteGroupMapping /// </summary> /// <param name="partyId"></param> /// <param name="newTopic"></param> /// <param name="logTrace"></param> protected async Task InsertNewGroupAsync(int partyId, SalesforceTopicMapping newTopic, ILogTrace logTrace) { // insert FMG Group var res = await AppStore.ContactsServiceClient.AddGroupAsync( new AddGroupRequest { PartyID = partyId, Name = newTopic.SalesforceTopicName } ); logTrace.Add(LogLevel.Info, "InsertNewGroupAsync() - Done" , new { newTopic.SalesforceTopicName, res.Status }); if (res.Status != HttpStatusCode.Created) { logTrace?.Add(LogLevel.Error, "InsertNewGroupAsync() - Failed", new { newTopic.SalesforceTopicName, res }); throw new Exception($"Failed to insert group {newTopic.SalesforceTopicName}"); } // insert the RemoteGroupMapping var groupId = res.Data.GroupID; var upsertRemoteGroupMappingResponse = await AppStore.RemoteDataServiceClient .UpsertRemoteGroupMappingAsync( new UpsertRemoteGroupMappingRequestData { PartyId = partyId, GroupId = groupId, RemoteGroupId = newTopic.SalesforceTopicId, RemoteGroupName = newTopic.SalesforceTopicName }, logTrace); logTrace.Add(LogLevel.Info, "UpsertRemoteGroupMapping() - Done" , new { newTopic.SalesforceTopicName, upsertRemoteGroupMappingResponse.Status }); }
/// <summary> /// Checks the then alert error to slack. /// </summary> /// <param name="jsonMsg">Json message.</param> /// <param name="ex">Ex.</param> /// <param name="logTrace">Log trace.</param> protected void CheckThenAlertErrorToSlack(TMessage jsonMsg, object reqData, Exception ex, ILogTrace logTrace) { if (!IsAlertToSlack(jsonMsg, reqData, logTrace)) { return; } AlertErrorToSlack(jsonMsg, ex, logTrace); }
/// <summary> /// Verify the current sync status of this Party /// </summary> /// <param name="partyId"></param> /// <param name="logTrace"></param> /// <returns> /// Return the SyncSetting /// </returns> /// <exception cref="IgnoreProcessingMessageException">When the sync status is not valid, should ignore</exception> protected async Task <GetByPartyIdResponseData> VerifySyncStatusAsync(int partyId, ILogTrace logTrace) { var title = "VerifySyncStatusAsync"; var syncSetting = await AppStore.SyncSettingV2ServiceClient.GetByPartyIdAsync( new GetByPartyIdRequestData { PartyId = partyId }, logTrace); if (syncSetting.Status == HttpStatusCode.NotFound) { throw new IgnoreProcessingMessageException(title, "Not set up yet"); } if (syncSetting.Status != HttpStatusCode.OK) { throw new Exception("Fail to get SyncSetting"); } if (syncSetting.Data.IntegrationType != CRMIntegrationTypes.Salesforce && syncSetting.Data.IntegrationType != CRMIntegrationTypes.Practifi) { throw new IgnoreProcessingMessageException(title, "IntegrationType is not Salesforce and Practifi"); } return(syncSetting.Data); }