public static JobQueueRequestResult GetResult(JobQueueRequest queueRequest) { if (queueRequest == null) { return(null); } object _lock = new object(); lock (_lock) { var queueRequestResult = new JobQueueRequestResult(); queueRequestResult.IntegrationId = queueRequest.JobInstances.Count > 0 ? queueRequest.JobInstances[0].Integration.Id : Guid.Empty; queueRequestResult.JobId = queueRequest.Job.Id; queueRequestResult.QueueRequestId = queueRequest.Id; queueRequestResult.InvocationSourceType = queueRequest.InvocationSourceType; queueRequestResult.Status = queueRequest.Status; var jobResults = new List <JobInstanceResult>(); foreach (var jobInstance in queueRequest.JobInstances) { jobResults.Add(GetResult(jobInstance)); } queueRequestResult.JobInstanceResults = jobResults; return(queueRequestResult); } }
/// <summary> /// /// </summary> /// <param name="jobInstanceId"></param> /// <returns>Returns null if a "sync object" no longer exists.</returns> public JobInstance GetJobInstanceFromQueueLog(Guid jobInstanceId, bool throwExceptionIfSyncObjectsAreDeletedOrDisabled = false) { if (!JobQueueManager.IsSafeForQueueLogRetrieval) { throw new Exception("The Job Queue Manager is in an unsafe state as job statuses may change. Queue retrieval from the database is disallowed."); } var configurator = new SyncEngineDatabaseConfigurator(_connectionString); using (var dbContext = new ls.QueueManagementDataContext(_connectionString)) { var jobInstanceInDbQueue = dbContext.JobQueues.Where(d => d.JobInstanceId == jobInstanceId).FirstOrDefault(); var integration = configurator.GetIntegrationByJobId(jobInstanceInDbQueue.JobId); if (integration == null || !integration.IsEnabled) { goto SyncObjectsForJobInstanceHaveChanged; } var job = integration.Jobs.Where(d => d.Id == jobInstanceInDbQueue.JobId).FirstOrDefault(); if (job == null || !job.IsEnabled) { goto SyncObjectsForJobInstanceHaveChanged; } var sourceDataSource = job.SourceDataSources.Values.Where(d => d.Id == jobInstanceInDbQueue.SourceDataSourceId).FirstOrDefault(); if (sourceDataSource == null) { goto SyncObjectsForJobInstanceHaveChanged; } if (job.TargetDataSource.Id != jobInstanceInDbQueue.TargetDataSourceId) { goto SyncObjectsForJobInstanceHaveChanged; } var jobStepInstancesInDbQueue = dbContext.JobStepQueues.Where(d => d.JobInstanceId == jobInstanceInDbQueue.JobInstanceId).ToList(); if (jobStepInstancesInDbQueue.Count == 0) { goto SyncObjectsForJobInstanceHaveChanged; } List <JobStepInstance> jobStepInstanceObjs = new List <JobStepInstance>(); foreach (var jobStepInstanceInDbQueue in jobStepInstancesInDbQueue) { var jobStep = job.Steps.Where(d => d.Id == jobStepInstanceInDbQueue.JobStepId).FirstOrDefault(); if (jobStep == null || !jobStep.IsEnabled) { goto SyncObjectsForJobInstanceHaveChanged; } var jobStepInstanceObj = new JobStepInstance(jobStepInstanceInDbQueue.JobStepInstanceId, jobStep, jobStepInstanceInDbQueue.OrderIndex); jobStepInstanceObj.Status = (JobStepQueueStatus)jobStepInstanceInDbQueue.JobStepQueueStatusId; jobStepInstanceObjs.Add(jobStepInstanceObj); } var filters = JobFilterHelper.ParseFromDatabaseText(jobInstanceInDbQueue.Filters); var invocationSourceType = jobInstanceInDbQueue.IsOnDemand == true ? JobInvocationSourceType.OnDemand : JobInvocationSourceType.Scheduled; var queueRequest = new JobQueueRequest(jobInstanceInDbQueue.QueueRequestId, integration, job, invocationSourceType); var jobInstanceObj = new JobInstance(queueRequest, jobInstanceInDbQueue.JobInstanceId, integration, job, sourceDataSource, job.TargetDataSource, jobStepInstanceObjs, jobInstanceInDbQueue.ScheduledStartTime, jobInstanceInDbQueue.InvocationSource, invocationSourceType, filters.ToList()); queueRequest.JobInstances.Add(jobInstanceObj); jobInstanceObj.Status = (JobQueueStatus)jobInstanceInDbQueue.JobQueueStatusId; return(jobInstanceObj); SyncObjectsForJobInstanceHaveChanged: if (throwExceptionIfSyncObjectsAreDeletedOrDisabled) { throw new Exception(string.Format("Queued job '{0}' in database logger has changed sync objects.", jobInstanceInDbQueue.JobInstanceId)); } else { return(null); } } }
public JobQueueRequestStatusChangedArgs(JobQueueRequest queueRequest) { QueueRequest = queueRequest; }
public JobInstance(JobQueueRequest queueRequest, Guid jobInstanceGuid, Integration integration, Job jobToRun, DataSource sourceDataSource, DataSource targetDataSource, List <JobStepInstance> jobStepInstances, DateTime scheduledStartTime, string invocationSource, JobInvocationSourceType invocationSourceType, List <JobFilter> filters = null) { if (integration == null) { throw new Exception("Integration can not be null."); } if (jobToRun == null) { throw new Exception("Job to run can not be null."); } if (sourceDataSource == null) { throw new Exception("Source-side data source can not be null."); } if (jobToRun.SourceDataSources.Where(d => d.Value.Id == sourceDataSource.Id).Count() == 0) { throw new Exception(string.Format("'{0}' ({1}) is not associated with job '{2}' ({3}) as a source-side data source.", sourceDataSource.Name, sourceDataSource.Id, jobToRun.Name, jobToRun.Id)); } if (targetDataSource == null) { throw new Exception("Target-side data source can not be null."); } if (jobToRun.TargetDataSource.Id != targetDataSource.Id) { throw new Exception(string.Format("'{0}' ({1}) is not associated with job '{2}' ({3}) as the target-side data source.", targetDataSource.Name, targetDataSource.Id, jobToRun.Name, jobToRun.Id)); } if (jobStepInstances == null || jobStepInstances.Count == 0) { throw new Exception(string.Format("At least one job step is required for queued job '{0}'. The job will not be executed.", jobToRun.Name)); } QueueRequest = queueRequest; if (jobInstanceGuid == Guid.Empty) { Id = Guid.NewGuid(); } else { Id = jobInstanceGuid; } Integration = integration; Job = jobToRun; if (JobQueueManager.Configurator == null) { SourceDataSource = new JobDataSource(SyncSide.Source, sourceDataSource); TargetDataSource = new JobDataSource(SyncSide.Target, targetDataSource); SyncEngineLogger.WriteToLog(LogEntryType.Warning, integration, "Update history could not be set for source and target data sources. No configurator has been set for the JobQueueManager."); } else { var runHistory = JobQueueManager.Configurator.GetJobDataSourceRunHistory(jobToRun.Id, sourceDataSource.Id, targetDataSource.Id); SourceDataSource = new JobDataSource(SyncSide.Source, sourceDataSource, runHistory); TargetDataSource = new JobDataSource(SyncSide.Target, targetDataSource, runHistory); } if (filters != null) { _filters = filters; } _jobStepInstances = jobStepInstances.OrderBy(d => d.OrderIndex).ToList(); ScheduledStartTime = scheduledStartTime; InvocationSource = invocationSource; InvocationSourceType = invocationSourceType; Id = Guid.NewGuid(); foreach (var jobStepInstance in _jobStepInstances) { jobStepInstance.AssociatedJobInstance = this; } }
public JobInstance(JobQueueRequest queueRequest, Integration integration, Job jobToRun, DataSource sourceDataSource, DataSource targetDataSource, List <JobStepInstance> jobStepInstances, DateTime scheduledStartTime, string invocationSource, JobInvocationSourceType invocationSourceType, List <JobFilter> filters = null) : this(queueRequest, Guid.Empty, integration, jobToRun, sourceDataSource, targetDataSource, jobStepInstances, scheduledStartTime, invocationSource, invocationSourceType, filters) { }
public static List <JobInstance> QueueJob(Integration integration, IEnumerable <DataSource> sourceSideDataSourcesToRun, Job jobToRun, DateTime scheduledStartTime, string invocationSource, JobInvocationSourceType invocationSourceType, List <JobFilter> filters = null) { if (integration == null) { throw new Exception("Integration is missing or empty."); } if (sourceSideDataSourcesToRun == null || sourceSideDataSourcesToRun.Where(d => d != null).Count() == 0) { throw new Exception(string.Format("At least one source-side data source is required to queue job '{0}'.", jobToRun.Name)); } foreach (var dataSource in sourceSideDataSourcesToRun) { if (!jobToRun.SourceDataSources.ContainsKey(dataSource.Name)) { throw new Exception(string.Format("Source-side data source '{0}' does not exist for job '{1}'. This job will not be queued for execution.", dataSource.Name, jobToRun.Name)); } } if (String.IsNullOrWhiteSpace(invocationSource)) { throw new Exception("Invocation source is missing or empty."); } if (!integration.IsEnabled) { throw new Exception(string.Format("Job '{0}' could not be queued for execution because integration '{1}' is disabled.", jobToRun.Name, integration.Name)); } if (!jobToRun.IsEnabled) { throw new Exception(string.Format("Job '{0}' could not be queued for execution because it is disabled.", jobToRun.Name)); } if (jobToRun.Steps.Where(d => d.IsEnabled).Count() == 0) { throw new Exception(string.Format("Job '{0}' could not be queued for execution because no job steps exist or all are disabled.", jobToRun.Name)); } SetMaxConcurrentThreadsForIntegration(integration); List <JobInstance> queuedJobs = new List <JobInstance>(); JobInstance jobInstance; JobStepInstance jobStepInstance; List <JobStepInstance> jobStepInstances; var queueRequest = new JobQueueRequest(integration, jobToRun, invocationSourceType); queueRequest.StatusChanged += new EventHandler <JobQueueRequestStatusChangedArgs>(HandleChangedQueueRequestStatus); queueRequest.Status = JobQueueRequestStatus.Waiting; foreach (var sourceSideDataSource in sourceSideDataSourcesToRun) { byte jobStepIdx = 0; jobStepInstances = new List <JobStepInstance>(); foreach (var jobStep in jobToRun.Steps) { if (jobStep.IsEnabled) { jobStepInstance = new JobStepInstance(jobStep, jobStepIdx); jobStepInstance.StatusChanged += new EventHandler <JobStepQueueStatusChangedArgs>(HandleChangedJobStepStatus); jobStepInstances.Add(jobStepInstance); //jobStepInstance.Status = JobStepQueueStatus.Waiting; jobStepIdx++; } } jobInstance = new JobInstance(queueRequest, integration, jobToRun, sourceSideDataSource, jobToRun.TargetDataSource, jobStepInstances, scheduledStartTime, invocationSource, invocationSourceType, filters); queueRequest.JobInstances.Add(jobInstance); // change the status here to avoid the job step not having an association with the job instance when status changes are logged foreach (var jobStepInstanceToFireStatusChangeFor in jobStepInstances) { jobStepInstanceToFireStatusChangeFor.Status = JobStepQueueStatus.Waiting; } jobInstance.StatusChanged += new EventHandler <JobQueueStatusChangedArgs>(HandleChangedJobStatus); if (waitingJobsByIntegrationId.ContainsKey(jobInstance.Integration.Id)) { waitingJobsByIntegrationId[jobInstance.Integration.Id].Add(jobInstance); } else { waitingJobsByIntegrationId.Add(jobInstance.Integration.Id, new List <JobInstance>() { jobInstance }); } // cache the job instance in memory if on-demand (temporary to get around OutOfMemoryException) if (jobInstance.InvocationSourceType == JobInvocationSourceType.OnDemand) { jobInstancesById.Add(jobInstance.Id, jobInstance); queueRequestsById.Add(queueRequest.Id, queueRequest); } jobInstance.Status = JobQueueStatus.Scheduled; queuedJobs.Add(jobInstance); if (JobQueued != null) { JobQueued(null, new JobQueuedArgs(jobInstance)); } } return(queuedJobs); }