async function createFullJobsList()

in x-pack/platform/plugins/shared/ml/server/models/job_service/jobs.ts [386:545]


  async function createFullJobsList(jobIds: string[] = []) {
    const jobs: CombinedJobWithStats[] = [];
    const groups: { [jobId: string]: string[] } = Object.create(null);
    const datafeeds: { [id: string]: DatafeedWithStats } = Object.create(null);
    const calendarsByJobId: { [jobId: string]: string[] } = Object.create(null);
    const globalCalendars: string[] = [];

    const jobIdsString = jobIds.join();

    const [
      jobResults,
      jobStatsResults,
      datafeedResults,
      datafeedStatsResults,
      calendarResults,
      latestBucketTimestampByJob,
    ] = await Promise.all([
      mlClient.getJobs(jobIds.length > 0 ? { job_id: jobIdsString } : undefined),
      mlClient.getJobStats(jobIds.length > 0 ? { job_id: jobIdsString } : undefined),
      mlClient.getDatafeeds(),
      mlClient.getDatafeedStats(),
      calMngr.getAllCalendars(),
      getLatestBucketTimestampByJob(),
    ]);

    if (datafeedResults && datafeedResults.datafeeds) {
      datafeedResults.datafeeds.forEach((datafeed) => {
        if (datafeedStatsResults && datafeedStatsResults.datafeeds) {
          const datafeedStats = datafeedStatsResults.datafeeds.find(
            (ds) => ds.datafeed_id === datafeed.datafeed_id
          );
          if (datafeedStats) {
            datafeeds[datafeed.job_id] = { ...datafeed, ...datafeedStats };
          }
        }
      });
    }

    // create list of jobs per group.
    // used for assigning calendars to jobs when a calendar has
    // only been attached to a group
    if (jobResults && jobResults.jobs) {
      jobResults.jobs.forEach((job) => {
        calendarsByJobId[job.job_id] = [];

        if (job.groups !== undefined) {
          job.groups.forEach((gId) => {
            if (groups[gId] === undefined) {
              groups[gId] = [];
            }
            groups[gId].push(job.job_id);
          });
        }
      });
    }

    // assign calendars to jobs
    if (calendarResults) {
      calendarResults.forEach((cal) => {
        cal.job_ids.forEach((id) => {
          if (id === GLOBAL_CALENDAR) {
            globalCalendars.push(cal.calendar_id);
          } else if (groups[id]) {
            groups[id].forEach((jId) => {
              if (calendarsByJobId[jId] !== undefined) {
                calendarsByJobId[jId].push(cal.calendar_id);
              }
            });
          } else {
            if (calendarsByJobId[id] !== undefined) {
              calendarsByJobId[id].push(cal.calendar_id);
            }
          }
        });
      });

      // de-duplicate calendars
      for (const cal in calendarsByJobId) {
        if (Object.hasOwn(calendarsByJobId, cal)) {
          calendarsByJobId[cal] = uniq(calendarsByJobId[cal]);
        }
      }
    }

    // create jobs objects containing job stats, datafeeds, datafeed stats and calendars
    if (jobResults && jobResults.jobs) {
      jobResults.jobs.forEach((job) => {
        let tempJob = job as CombinedJobWithStats;

        const calendars: string[] = [
          ...(calendarsByJobId[tempJob.job_id] || []),
          ...(globalCalendars || []),
        ];
        if (calendars.length) {
          tempJob.calendars = calendars;
        }

        if (jobStatsResults && jobStatsResults.jobs) {
          const jobStats = jobStatsResults.jobs.find((js) => js.job_id === tempJob.job_id);
          if (jobStats !== undefined) {
            tempJob = { ...tempJob, ...jobStats };
            if (jobStats.node) {
              tempJob.node = jobStats.node;
            }
            if (jobStats.open_time) {
              tempJob.open_time = jobStats.open_time;
            }

            // Add in the timestamp of the last bucket processed for each job if available.
            const latestBucketTimestamp =
              latestBucketTimestampByJob && latestBucketTimestampByJob[tempJob.job_id];
            if (latestBucketTimestamp) {
              tempJob.data_counts.latest_bucket_timestamp = latestBucketTimestamp;
            }
          }
        }

        const datafeed = datafeeds[tempJob.job_id];
        if (datafeed !== undefined) {
          tempJob.datafeed_config = datafeed;
        }

        jobs.push(tempJob);
      });

      if (rulesClient) {
        const mlAlertingRules = await rulesClient.find<MlAnomalyDetectionAlertParams>({
          options: {
            filter: `alert.attributes.alertTypeId:${ML_ALERT_TYPES.ANOMALY_DETECTION}`,
            perPage: 1000,
          },
        });

        mlAlertingRules.data.forEach((curr) => {
          const {
            params: {
              jobSelection: { jobIds: ruleJobIds, groupIds: ruleGroupIds },
            },
          } = curr;

          jobs.forEach((j) => {
            const isIncluded =
              (Array.isArray(ruleJobIds) && ruleJobIds.includes(j.job_id)) ||
              (Array.isArray(ruleGroupIds) &&
                Array.isArray(j.groups) &&
                j.groups.some((g) => ruleGroupIds.includes(g)));

            if (isIncluded) {
              if (Array.isArray(j.alerting_rules)) {
                j.alerting_rules.push(curr);
              } else {
                j.alerting_rules = [curr];
              }
            }
          });
        });
      }
    }
    return jobs;
  }