Nessuna descrizione
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

cloudscheduler.js 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.jobFromEndpoint = exports.topicNameForEndpoint = exports.jobNameForEndpoint = exports.createOrReplaceJob = exports.getJob = exports.deleteJob = void 0;
  4. const _ = require("lodash");
  5. const error_1 = require("../error");
  6. const logger_1 = require("../logger");
  7. const api_1 = require("../api");
  8. const apiv2_1 = require("../apiv2");
  9. const backend = require("../deploy/functions/backend");
  10. const proto = require("./proto");
  11. const checkIam_1 = require("../deploy/functions/checkIam");
  12. const functional_1 = require("../functional");
  13. const VERSION = "v1";
  14. const DEFAULT_TIME_ZONE_V1 = "America/Los_Angeles";
  15. const DEFAULT_TIME_ZONE_V2 = "UTC";
  16. const apiClient = new apiv2_1.Client({ urlPrefix: api_1.cloudschedulerOrigin, apiVersion: VERSION });
  17. function createJob(job) {
  18. const strippedName = job.name.substring(0, job.name.lastIndexOf("/"));
  19. const json = job.pubsubTarget
  20. ? Object.assign({ timeZone: DEFAULT_TIME_ZONE_V1 }, job) : Object.assign({ timeZone: DEFAULT_TIME_ZONE_V2 }, job);
  21. return apiClient.post(`/${strippedName}`, json);
  22. }
  23. function deleteJob(name) {
  24. return apiClient.delete(`/${name}`);
  25. }
  26. exports.deleteJob = deleteJob;
  27. function getJob(name) {
  28. return apiClient.get(`/${name}`, {
  29. resolveOnHTTPError: true,
  30. });
  31. }
  32. exports.getJob = getJob;
  33. function updateJob(job) {
  34. let fieldMasks;
  35. let json;
  36. if (job.pubsubTarget) {
  37. fieldMasks = proto.fieldMasks(job, "pubsubTarget");
  38. json = Object.assign({ timeZone: DEFAULT_TIME_ZONE_V1 }, job);
  39. }
  40. else {
  41. fieldMasks = proto.fieldMasks(job, "httpTarget");
  42. json = Object.assign({ timeZone: DEFAULT_TIME_ZONE_V2 }, job);
  43. }
  44. return apiClient.patch(`/${job.name}`, json, {
  45. queryParams: {
  46. updateMask: fieldMasks.join(","),
  47. },
  48. });
  49. }
  50. async function createOrReplaceJob(job) {
  51. var _a, _b;
  52. const jobName = job.name.split("/").pop();
  53. const existingJob = await getJob(job.name);
  54. if (existingJob.status === 404) {
  55. let newJob;
  56. try {
  57. newJob = await createJob(job);
  58. }
  59. catch (err) {
  60. if (((_b = (_a = err === null || err === void 0 ? void 0 : err.context) === null || _a === void 0 ? void 0 : _a.response) === null || _b === void 0 ? void 0 : _b.statusCode) === 404) {
  61. throw new error_1.FirebaseError(`Cloud resource location is not set for this project but scheduled functions require it. ` +
  62. `Please see this documentation for more details: https://firebase.google.com/docs/projects/locations.`);
  63. }
  64. throw new error_1.FirebaseError(`Failed to create scheduler job ${job.name}: ${err.message}`);
  65. }
  66. logger_1.logger.debug(`created scheduler job ${jobName}`);
  67. return newJob;
  68. }
  69. if (!job.timeZone) {
  70. job.timeZone = job.pubsubTarget ? DEFAULT_TIME_ZONE_V1 : DEFAULT_TIME_ZONE_V2;
  71. }
  72. if (!needUpdate(existingJob.body, job)) {
  73. logger_1.logger.debug(`scheduler job ${jobName} is up to date, no changes required`);
  74. return;
  75. }
  76. const updatedJob = await updateJob(job);
  77. logger_1.logger.debug(`updated scheduler job ${jobName}`);
  78. return updatedJob;
  79. }
  80. exports.createOrReplaceJob = createOrReplaceJob;
  81. function needUpdate(existingJob, newJob) {
  82. if (!existingJob) {
  83. return true;
  84. }
  85. if (!newJob) {
  86. return true;
  87. }
  88. if (existingJob.schedule !== newJob.schedule) {
  89. return true;
  90. }
  91. if (existingJob.timeZone !== newJob.timeZone) {
  92. return true;
  93. }
  94. if (newJob.retryConfig) {
  95. if (!existingJob.retryConfig) {
  96. return true;
  97. }
  98. if (!_.isMatch(existingJob.retryConfig, newJob.retryConfig)) {
  99. return true;
  100. }
  101. }
  102. return false;
  103. }
  104. function jobNameForEndpoint(endpoint, location) {
  105. const id = backend.scheduleIdForFunction(endpoint);
  106. return `projects/${endpoint.project}/locations/${location}/jobs/${id}`;
  107. }
  108. exports.jobNameForEndpoint = jobNameForEndpoint;
  109. function topicNameForEndpoint(endpoint) {
  110. const id = backend.scheduleIdForFunction(endpoint);
  111. return `projects/${endpoint.project}/topics/${id}`;
  112. }
  113. exports.topicNameForEndpoint = topicNameForEndpoint;
  114. function jobFromEndpoint(endpoint, location, projectNumber) {
  115. const job = {};
  116. job.name = jobNameForEndpoint(endpoint, location);
  117. if (endpoint.platform === "gcfv1") {
  118. job.timeZone = endpoint.scheduleTrigger.timeZone || DEFAULT_TIME_ZONE_V1;
  119. job.pubsubTarget = {
  120. topicName: topicNameForEndpoint(endpoint),
  121. attributes: {
  122. scheduled: "true",
  123. },
  124. };
  125. }
  126. else if (endpoint.platform === "gcfv2") {
  127. job.timeZone = endpoint.scheduleTrigger.timeZone || DEFAULT_TIME_ZONE_V2;
  128. job.httpTarget = {
  129. uri: endpoint.uri,
  130. httpMethod: "POST",
  131. oidcToken: {
  132. serviceAccountEmail: (0, checkIam_1.getDefaultComputeServiceAgent)(projectNumber),
  133. },
  134. };
  135. }
  136. else {
  137. (0, functional_1.assertExhaustive)(endpoint.platform);
  138. }
  139. if (!endpoint.scheduleTrigger.schedule) {
  140. throw new error_1.FirebaseError("Cannot create a scheduler job without a schedule:" + JSON.stringify(endpoint));
  141. }
  142. job.schedule = endpoint.scheduleTrigger.schedule;
  143. if (endpoint.scheduleTrigger.retryConfig) {
  144. job.retryConfig = {};
  145. proto.copyIfPresent(job.retryConfig, endpoint.scheduleTrigger.retryConfig, "maxDoublings", "retryCount");
  146. proto.convertIfPresent(job.retryConfig, endpoint.scheduleTrigger.retryConfig, "maxBackoffDuration", "maxBackoffSeconds", (0, functional_1.nullsafeVisitor)(proto.durationFromSeconds));
  147. proto.convertIfPresent(job.retryConfig, endpoint.scheduleTrigger.retryConfig, "minBackoffDuration", "minBackoffSeconds", (0, functional_1.nullsafeVisitor)(proto.durationFromSeconds));
  148. proto.convertIfPresent(job.retryConfig, endpoint.scheduleTrigger.retryConfig, "maxRetryDuration", "maxRetrySeconds", (0, functional_1.nullsafeVisitor)(proto.durationFromSeconds));
  149. if (!Object.keys(job.retryConfig).length) {
  150. delete job.retryConfig;
  151. }
  152. }
  153. return job;
  154. }
  155. exports.jobFromEndpoint = jobFromEndpoint;