@aws-cdk/aws-glue-alpha 2.176.0-alpha.0 → 2.177.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.jsii +5851 -3571
- package/.jsii.tabl.json.gz +0 -0
- package/.warnings.jsii.js +525 -235
- package/README.md +422 -159
- package/awslint.json +5 -5
- package/lib/code.js +4 -4
- package/lib/connection.js +3 -3
- package/lib/constants.d.ts +261 -0
- package/lib/constants.js +281 -0
- package/lib/data-format.js +5 -5
- package/lib/data-quality-ruleset.js +2 -2
- package/lib/database.js +2 -2
- package/lib/external-table.js +1 -1
- package/lib/index.d.ts +13 -2
- package/lib/index.js +14 -3
- package/lib/jobs/job.d.ts +393 -0
- package/lib/jobs/job.js +299 -0
- package/lib/jobs/pyspark-etl-job.d.ts +81 -0
- package/lib/jobs/pyspark-etl-job.js +127 -0
- package/lib/jobs/pyspark-flex-etl-job.d.ts +83 -0
- package/lib/jobs/pyspark-flex-etl-job.js +134 -0
- package/lib/jobs/pyspark-streaming-job.d.ts +82 -0
- package/lib/jobs/pyspark-streaming-job.js +128 -0
- package/lib/jobs/python-shell-job.d.ts +55 -0
- package/lib/jobs/python-shell-job.js +96 -0
- package/lib/jobs/ray-job.d.ts +44 -0
- package/lib/jobs/ray-job.js +87 -0
- package/lib/jobs/scala-spark-etl-job.d.ts +78 -0
- package/lib/jobs/scala-spark-etl-job.js +131 -0
- package/lib/jobs/scala-spark-flex-etl-job.d.ts +109 -0
- package/lib/jobs/scala-spark-flex-etl-job.js +140 -0
- package/lib/jobs/scala-spark-streaming-job.d.ts +77 -0
- package/lib/jobs/scala-spark-streaming-job.js +128 -0
- package/lib/jobs/spark-ui-utils.d.ts +53 -0
- package/lib/jobs/spark-ui-utils.js +26 -0
- package/lib/s3-table.d.ts +4 -4
- package/lib/s3-table.js +2 -2
- package/lib/schema.d.ts +1 -1
- package/lib/schema.js +2 -2
- package/lib/security-configuration.js +2 -2
- package/lib/storage-parameter.js +1 -1
- package/lib/table-base.js +2 -2
- package/lib/table-deprecated.js +1 -1
- package/lib/triggers/trigger-options.d.ts +205 -0
- package/lib/triggers/trigger-options.js +39 -0
- package/lib/triggers/workflow.d.ts +203 -0
- package/lib/triggers/workflow.js +368 -0
- package/package.json +8 -8
- package/rosetta/default.ts-fixture +1 -1
- package/lib/job-executable.d.ts +0 -384
- package/lib/job-executable.js +0 -348
- package/lib/job.d.ts +0 -574
- package/lib/job.js +0 -531
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import * as iam from 'aws-cdk-lib/aws-iam';
|
|
2
|
+
import { Job, JobProperties } from './job';
|
|
3
|
+
import { Construct } from 'constructs';
|
|
4
|
+
import { SparkUIProps, SparkUILoggingLocation } from './spark-ui-utils';
|
|
5
|
+
import * as cdk from 'aws-cdk-lib/core';
|
|
6
|
+
import { Code } from '../code';
|
|
7
|
+
/**
|
|
8
|
+
* Properties for PySparkFlexEtlJob
|
|
9
|
+
*/
|
|
10
|
+
export interface PySparkFlexEtlJobProps extends JobProperties {
|
|
11
|
+
/**
|
|
12
|
+
* Enables the Spark UI debugging and monitoring with the specified props.
|
|
13
|
+
*
|
|
14
|
+
* @default - Spark UI debugging and monitoring is disabled.
|
|
15
|
+
*
|
|
16
|
+
* @see https://docs.aws.amazon.com/glue/latest/dg/monitor-spark-ui-jobs.html
|
|
17
|
+
* @see https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-glue-arguments.html
|
|
18
|
+
*/
|
|
19
|
+
readonly sparkUI?: SparkUIProps;
|
|
20
|
+
/**
|
|
21
|
+
* Specifies configuration properties of a notification (optional).
|
|
22
|
+
* After a job run starts, the number of minutes to wait before sending a job run delay notification.
|
|
23
|
+
* @default - undefined
|
|
24
|
+
*/
|
|
25
|
+
readonly notifyDelayAfter?: cdk.Duration;
|
|
26
|
+
/**
|
|
27
|
+
* Additional Python files that AWS Glue adds to the Python path before executing your script.
|
|
28
|
+
*
|
|
29
|
+
* @default - no extra python files specified.
|
|
30
|
+
*
|
|
31
|
+
* @see https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-glue-arguments.html
|
|
32
|
+
*/
|
|
33
|
+
readonly extraPythonFiles?: Code[];
|
|
34
|
+
/**
|
|
35
|
+
* Additional files, such as configuration files that AWS Glue copies to the working directory of your script before executing it.
|
|
36
|
+
*
|
|
37
|
+
* @default - no extra files specified.
|
|
38
|
+
*
|
|
39
|
+
* @see https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-glue-arguments.html
|
|
40
|
+
*/
|
|
41
|
+
readonly extraFiles?: Code[];
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Flex Jobs class
|
|
45
|
+
*
|
|
46
|
+
* Flex jobs supports Python and Scala language.
|
|
47
|
+
* The flexible execution class is appropriate for non-urgent jobs such as
|
|
48
|
+
* pre-production jobs, testing, and one-time data loads.
|
|
49
|
+
* Flexible job runs are supported for jobs using AWS Glue version 3.0 or later and G.1X or
|
|
50
|
+
* G.2X worker types but will default to the latest version of Glue (currently Glue 3.0.)
|
|
51
|
+
*
|
|
52
|
+
* Similar to ETL, we’ll enable these features: —enable-metrics, —enable-spark-ui,
|
|
53
|
+
* —enable-continuous-cloudwatch-log
|
|
54
|
+
*/
|
|
55
|
+
export declare class PySparkFlexEtlJob extends Job {
|
|
56
|
+
readonly jobArn: string;
|
|
57
|
+
readonly jobName: string;
|
|
58
|
+
readonly role: iam.IRole;
|
|
59
|
+
readonly grantPrincipal: iam.IPrincipal;
|
|
60
|
+
/**
|
|
61
|
+
* The Spark UI logs location if Spark UI monitoring and debugging is enabled.
|
|
62
|
+
*
|
|
63
|
+
* @see https://docs.aws.amazon.com/glue/latest/dg/monitor-spark-ui-jobs.html
|
|
64
|
+
* @see https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-glue-arguments.html
|
|
65
|
+
*/
|
|
66
|
+
readonly sparkUILoggingLocation?: SparkUILoggingLocation;
|
|
67
|
+
/**
|
|
68
|
+
* PySparkFlexEtlJob constructor
|
|
69
|
+
*/
|
|
70
|
+
constructor(scope: Construct, id: string, props: PySparkFlexEtlJobProps);
|
|
71
|
+
/**
|
|
72
|
+
*Set the executable arguments with best practices enabled by default
|
|
73
|
+
*
|
|
74
|
+
* @returns An array of arguments for Glue to use on execution
|
|
75
|
+
*/
|
|
76
|
+
private executableArguments;
|
|
77
|
+
/**
|
|
78
|
+
* Set the arguments for sparkUI with best practices enabled by default
|
|
79
|
+
*
|
|
80
|
+
* @returns An array of arguments for enabling sparkUI
|
|
81
|
+
*/
|
|
82
|
+
private setupSparkUI;
|
|
83
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.PySparkFlexEtlJob = void 0;
|
|
5
|
+
const jsiiDeprecationWarnings = require("../../.warnings.jsii.js");
|
|
6
|
+
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
|
7
|
+
const iam = require("aws-cdk-lib/aws-iam");
|
|
8
|
+
const aws_s3_1 = require("aws-cdk-lib/aws-s3");
|
|
9
|
+
const aws_glue_1 = require("aws-cdk-lib/aws-glue");
|
|
10
|
+
const job_1 = require("./job");
|
|
11
|
+
const constants_1 = require("../constants");
|
|
12
|
+
const spark_ui_utils_1 = require("./spark-ui-utils");
|
|
13
|
+
/**
|
|
14
|
+
* Flex Jobs class
|
|
15
|
+
*
|
|
16
|
+
* Flex jobs supports Python and Scala language.
|
|
17
|
+
* The flexible execution class is appropriate for non-urgent jobs such as
|
|
18
|
+
* pre-production jobs, testing, and one-time data loads.
|
|
19
|
+
* Flexible job runs are supported for jobs using AWS Glue version 3.0 or later and G.1X or
|
|
20
|
+
* G.2X worker types but will default to the latest version of Glue (currently Glue 3.0.)
|
|
21
|
+
*
|
|
22
|
+
* Similar to ETL, we’ll enable these features: —enable-metrics, —enable-spark-ui,
|
|
23
|
+
* —enable-continuous-cloudwatch-log
|
|
24
|
+
*/
|
|
25
|
+
class PySparkFlexEtlJob extends job_1.Job {
|
|
26
|
+
/**
|
|
27
|
+
* PySparkFlexEtlJob constructor
|
|
28
|
+
*/
|
|
29
|
+
constructor(scope, id, props) {
|
|
30
|
+
super(scope, id, {
|
|
31
|
+
physicalName: props.jobName,
|
|
32
|
+
});
|
|
33
|
+
try {
|
|
34
|
+
jsiiDeprecationWarnings._aws_cdk_aws_glue_alpha_PySparkFlexEtlJobProps(props);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
|
38
|
+
Error.captureStackTrace(error, PySparkFlexEtlJob);
|
|
39
|
+
}
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
42
|
+
// Set up role and permissions for principal
|
|
43
|
+
this.role = props.role, {
|
|
44
|
+
assumedBy: new iam.ServicePrincipal('glue.amazonaws.com'),
|
|
45
|
+
managedPolicies: [iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSGlueServiceRole')],
|
|
46
|
+
};
|
|
47
|
+
this.grantPrincipal = this.role;
|
|
48
|
+
// Enable SparkUI by default as a best practice
|
|
49
|
+
const sparkUIArgs = props.sparkUI?.bucket ? this.setupSparkUI(this.role, props.sparkUI) : undefined;
|
|
50
|
+
this.sparkUILoggingLocation = sparkUIArgs?.location;
|
|
51
|
+
// Enable CloudWatch metrics and continuous logging by default as a best practice
|
|
52
|
+
const continuousLoggingArgs = this.setupContinuousLogging(this.role, props.continuousLogging);
|
|
53
|
+
const profilingMetricsArgs = { '--enable-metrics': '' };
|
|
54
|
+
const observabilityMetricsArgs = { '--enable-observability-metrics': 'true' };
|
|
55
|
+
// Gather executable arguments
|
|
56
|
+
const execuatbleArgs = this.executableArguments(props);
|
|
57
|
+
// Conbine command line arguments into a single line item
|
|
58
|
+
const defaultArguments = {
|
|
59
|
+
...execuatbleArgs,
|
|
60
|
+
...continuousLoggingArgs,
|
|
61
|
+
...profilingMetricsArgs,
|
|
62
|
+
...observabilityMetricsArgs,
|
|
63
|
+
...sparkUIArgs?.args,
|
|
64
|
+
...this.checkNoReservedArgs(props.defaultArguments),
|
|
65
|
+
};
|
|
66
|
+
const jobResource = new aws_glue_1.CfnJob(this, 'Resource', {
|
|
67
|
+
name: props.jobName,
|
|
68
|
+
description: props.description,
|
|
69
|
+
role: this.role.roleArn,
|
|
70
|
+
command: {
|
|
71
|
+
name: constants_1.JobType.ETL,
|
|
72
|
+
scriptLocation: this.codeS3ObjectUrl(props.script),
|
|
73
|
+
pythonVersion: constants_1.PythonVersion.THREE,
|
|
74
|
+
},
|
|
75
|
+
glueVersion: props.glueVersion ? props.glueVersion : constants_1.GlueVersion.V3_0,
|
|
76
|
+
workerType: props.workerType ? props.workerType : constants_1.WorkerType.G_1X,
|
|
77
|
+
numberOfWorkers: props.numberOfWorkers ? props.numberOfWorkers : 10,
|
|
78
|
+
maxRetries: props.maxRetries,
|
|
79
|
+
executionProperty: props.maxConcurrentRuns ? { maxConcurrentRuns: props.maxConcurrentRuns } : undefined,
|
|
80
|
+
notificationProperty: props.notifyDelayAfter ? { notifyDelayAfter: props.notifyDelayAfter.toMinutes() } : undefined,
|
|
81
|
+
timeout: props.timeout?.toMinutes(),
|
|
82
|
+
connections: props.connections ? { connections: props.connections.map((connection) => connection.connectionName) } : undefined,
|
|
83
|
+
securityConfiguration: props.securityConfiguration?.securityConfigurationName,
|
|
84
|
+
tags: props.tags,
|
|
85
|
+
executionClass: constants_1.ExecutionClass.FLEX,
|
|
86
|
+
jobRunQueuingEnabled: false,
|
|
87
|
+
defaultArguments,
|
|
88
|
+
});
|
|
89
|
+
const resourceName = this.getResourceNameAttribute(jobResource.ref);
|
|
90
|
+
this.jobArn = this.buildJobArn(this, resourceName);
|
|
91
|
+
this.jobName = resourceName;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
*Set the executable arguments with best practices enabled by default
|
|
95
|
+
*
|
|
96
|
+
* @returns An array of arguments for Glue to use on execution
|
|
97
|
+
*/
|
|
98
|
+
executableArguments(props) {
|
|
99
|
+
const args = {};
|
|
100
|
+
args['--job-language'] = constants_1.JobLanguage.PYTHON;
|
|
101
|
+
if (props.extraPythonFiles && props.extraPythonFiles.length > 0) {
|
|
102
|
+
args['--extra-py-files'] = props.extraPythonFiles.map(code => this.codeS3ObjectUrl(code)).join(',');
|
|
103
|
+
}
|
|
104
|
+
if (props.extraFiles && props.extraFiles.length > 0) {
|
|
105
|
+
args['--extra-files'] = props.extraFiles.map(code => this.codeS3ObjectUrl(code)).join(',');
|
|
106
|
+
}
|
|
107
|
+
return args;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Set the arguments for sparkUI with best practices enabled by default
|
|
111
|
+
*
|
|
112
|
+
* @returns An array of arguments for enabling sparkUI
|
|
113
|
+
*/
|
|
114
|
+
setupSparkUI(role, sparkUiProps) {
|
|
115
|
+
(0, spark_ui_utils_1.validateSparkUiPrefix)(sparkUiProps.prefix);
|
|
116
|
+
const bucket = sparkUiProps.bucket ?? new aws_s3_1.Bucket(this, 'SparkUIBucket', { enforceSSL: true, encryption: aws_s3_1.BucketEncryption.S3_MANAGED });
|
|
117
|
+
bucket.grantReadWrite(role, (0, spark_ui_utils_1.cleanSparkUiPrefixForGrant)(sparkUiProps.prefix));
|
|
118
|
+
const args = {
|
|
119
|
+
'--enable-spark-ui': 'true',
|
|
120
|
+
'--spark-event-logs-path': bucket.s3UrlForObject(sparkUiProps.prefix).replace(/\/?$/, '/'), // path will always end with a slash
|
|
121
|
+
};
|
|
122
|
+
return {
|
|
123
|
+
location: {
|
|
124
|
+
prefix: sparkUiProps.prefix,
|
|
125
|
+
bucket,
|
|
126
|
+
},
|
|
127
|
+
args,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
exports.PySparkFlexEtlJob = PySparkFlexEtlJob;
|
|
132
|
+
_a = JSII_RTTI_SYMBOL_1;
|
|
133
|
+
PySparkFlexEtlJob[_a] = { fqn: "@aws-cdk/aws-glue-alpha.PySparkFlexEtlJob", version: "2.177.0-alpha.0" };
|
|
134
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHlzcGFyay1mbGV4LWV0bC1qb2IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJweXNwYXJrLWZsZXgtZXRsLWpvYi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSwyQ0FBMkM7QUFDM0MsK0NBQThEO0FBQzlELG1EQUE4QztBQUM5QywrQkFBMkM7QUFFM0MsNENBQTRHO0FBQzVHLHFEQUEySDtBQTZDM0g7Ozs7Ozs7Ozs7O0dBV0c7QUFDSCxNQUFhLGlCQUFrQixTQUFRLFNBQUc7SUFjeEM7O09BRUc7SUFDSCxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQTZCO1FBQ3JFLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFO1lBQ2YsWUFBWSxFQUFFLEtBQUssQ0FBQyxPQUFPO1NBQzVCLENBQUMsQ0FBQzs7Ozs7OytDQXBCTSxpQkFBaUI7Ozs7UUFzQjFCLDRDQUE0QztRQUM1QyxJQUFJLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQyxJQUFJLEVBQUU7WUFDdEIsU0FBUyxFQUFFLElBQUksR0FBRyxDQUFDLGdCQUFnQixDQUFDLG9CQUFvQixDQUFDO1lBQ3pELGVBQWUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsd0JBQXdCLENBQUMsaUNBQWlDLENBQUMsQ0FBQztTQUNqRyxDQUFDO1FBQ0YsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO1FBRWhDLCtDQUErQztRQUMvQyxNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1FBQ3BHLElBQUksQ0FBQyxzQkFBc0IsR0FBRyxXQUFXLEVBQUUsUUFBUSxDQUFDO1FBRXBELGlGQUFpRjtRQUNqRixNQUFNLHFCQUFxQixHQUFHLElBQUksQ0FB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LElBQUksRUFBRSxJQUFBLDJDQUEwQixFQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1FBQzdFLE1BQU0sSUFBSSxHQUFHO1lBQ1gsbUJBQW1CLEVBQUUsTUFBTTtZQUMzQix5QkFBeUIsRUFBRSxNQUFNLENBQUMsY0FBYyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxFQUFFLG9DQUFvQztTQUNqSSxDQUFDO1FBRUYsT0FBTztZQUNMLFFBQVEsRUFBRTtnQkFDUixNQUFNLEVBQUUsWUFBWSxDQUFDLE1BQU07Z0JBQzNCLE1BQU07YUFDUDtZQUNELElBQUk7U0FDTCxDQUFDO0tBQ0g7O0FBM0hILDhDQTRIQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGlhbSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtaWFtJztcbmltcG9ydCB7IEJ1Y2tldCwgQnVja2V0RW5jcnlwdGlvbiB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1zMyc7XG5pbXBvcnQgeyBDZm5Kb2IgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZ2x1ZSc7XG5pbXBvcnQgeyBKb2IsIEpvYlByb3BlcnRpZXMgfSBmcm9tICcuL2pvYic7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB7IEpvYlR5cGUsIEdsdWVWZXJzaW9uLCBKb2JMYW5ndWFnZSwgUHl0aG9uVmVyc2lvbiwgV29ya2VyVHlwZSwgRXhlY3V0aW9uQ2xhc3MgfSBmcm9tICcuLi9jb25zdGFudHMnO1xuaW1wb3J0IHsgU3BhcmtVSVByb3BzLCBTcGFya1VJTG9nZ2luZ0xvY2F0aW9uLCB2YWxpZGF0ZVNwYXJrVWlQcmVmaXgsIGNsZWFuU3BhcmtVaVByZWZpeEZvckdyYW50IH0gZnJvbSAnLi9zcGFyay11aS11dGlscyc7XG5pbXBvcnQgKiBhcyBjZGsgZnJvbSAnYXdzLWNkay1saWIvY29yZSc7XG5pbXBvcnQgeyBDb2RlIH0gZnJvbSAnLi4vY29kZSc7XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgUHlTcGFya0ZsZXhFdGxKb2JcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQeVNwYXJrRmxleEV0bEpvYlByb3BzIGV4dGVuZHMgSm9iUHJvcGVydGllcyB7XG4gIC8qKlxuICAgKiBFbmFibGVzIHRoZSBTcGFyayBVSSBkZWJ1Z2dpbmcgYW5kIG1vbml0b3Jpbmcgd2l0aCB0aGUgc3BlY2lmaWVkIHByb3BzLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIFNwYXJrIFVJIGRlYnVnZ2luZyBhbmQgbW9uaXRvcmluZyBpcyBkaXNhYmxlZC5cbiAgICpcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZ2x1ZS9sYXRlc3QvZGcvbW9uaXRvci1zcGFyay11aS1qb2JzLmh0bWxcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZ2x1ZS9sYXRlc3QvZGcvYXdzLWdsdWUtcHJvZ3JhbW1pbmctZXRsLWdsdWUtYXJndW1lbnRzLmh0bWxcbiAgICovXG4gIHJlYWRvbmx5IHNwYXJrVUk/OiBTcGFya1VJUHJvcHM7XG5cbiAgLyoqXG4gICAqIFNwZWNpZmllcyBjb25maWd1cmF0aW9uIHByb3BlcnRpZXMgb2YgYSBub3RpZmljYXRpb24gKG9wdGlvbmFsKS5cbiAgICogQWZ0ZXIgYSBqb2IgcnVuIHN0YXJ0cywgdGhlIG51bWJlciBvZiBtaW51dGVzIHRvIHdhaXQgYmVmb3JlIHNlbmRpbmcgYSBqb2IgcnVuIGRlbGF5IG5vdGlmaWNhdGlvbi5cbiAgICogQGRlZmF1bHQgLSB1bmRlZmluZWRcbiAgICovXG4gIHJlYWRvbmx5IG5vdGlmeURlbGF5QWZ0ZXI/OiBjZGsuRHVyYXRpb247XG5cbiAgLyoqXG4gICAqIEFkZGl0aW9uYWwgUHl0aG9uIGZpbGVzIHRoYXQgQVdTIEdsdWUgYWRkcyB0byB0aGUgUHl0aG9uIHBhdGggYmVmb3JlIGV4ZWN1dGluZyB5b3VyIHNjcmlwdC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBubyBleHRyYSBweXRob24gZmlsZXMgc3BlY2lmaWVkLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9nbHVlL2xhdGVzdC9kZy9hd3MtZ2x1ZS1wcm9ncmFtbWluZy1ldGwtZ2x1ZS1hcmd1bWVudHMuaHRtbFxuICAgKi9cbiAgcmVhZG9ubHkgZXh0cmFQeXRob25GaWxlcz86IENvZGVbXTtcblxuICAvKipcbiAgICogQWRkaXRpb25hbCBmaWxlcywgc3VjaCBhcyBjb25maWd1cmF0aW9uIGZpbGVzIHRoYXQgQVdTIEdsdWUgY29waWVzIHRvIHRoZSB3b3JraW5nIGRpcmVjdG9yeSBvZiB5b3VyIHNjcmlwdCBiZWZvcmUgZXhlY3V0aW5nIGl0LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIGV4dHJhIGZpbGVzIHNwZWNpZmllZC5cbiAgICpcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZ2x1ZS9sYXRlc3QvZGcvYXdzLWdsdWUtcHJvZ3JhbW1pbmctZXRsLWdsdWUtYXJndW1lbnRzLmh0bWxcbiAgICovXG4gIHJlYWRvbmx5IGV4dHJhRmlsZXM/OiBDb2RlW107XG5cbn1cblxuLyoqXG4gKiBGbGV4IEpvYnMgY2xhc3NcbiAqXG4gKiBGbGV4IGpvYnMgc3VwcG9ydHMgUHl0aG9uIGFuZCBTY2FsYSBsYW5ndWFnZS5cbiAqIFRoZSBmbGV4aWJsZSBleGVjdXRpb24gY2xhc3MgaXMgYXBwcm9wcmlhdGUgZm9yIG5vbi11cmdlbnQgam9icyBzdWNoIGFzXG4gKiBwcmUtcHJvZHVjdGlvbiBqb2JzLCB0ZXN0aW5nLCBhbmQgb25lLXRpbWUgZGF0YSBsb2Fkcy5cbiAqIEZsZXhpYmxlIGpvYiBydW5zIGFyZSBzdXBwb3J0ZWQgZm9yIGpvYnMgdXNpbmcgQVdTIEdsdWUgdmVyc2lvbiAzLjAgb3IgbGF0ZXIgYW5kIEcuMVggb3JcbiAqIEcuMlggd29ya2VyIHR5cGVzIGJ1dCB3aWxsIGRlZmF1bHQgdG8gdGhlIGxhdGVzdCB2ZXJzaW9uIG9mIEdsdWUgKGN1cnJlbnRseSBHbHVlIDMuMC4pXG4gKlxuICogU2ltaWxhciB0byBFVEwsIHdl4oCZbGwgZW5hYmxlIHRoZXNlIGZlYXR1cmVzOiDigJRlbmFibGUtbWV0cmljcywg4oCUZW5hYmxlLXNwYXJrLXVpLFxuICog4oCUZW5hYmxlLWNvbnRpbnVvdXMtY2xvdWR3YXRjaC1sb2dcbiAqL1xuZXhwb3J0IGNsYXNzIFB5U3BhcmtGbGV4RXRsSm9iIGV4dGVuZHMgSm9iIHtcbiAgcHVibGljIHJlYWRvbmx5IGpvYkFybjogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgam9iTmFtZTogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgcm9sZTogaWFtLklSb2xlO1xuICBwdWJsaWMgcmVhZG9ubHkgZ3JhbnRQcmluY2lwYWw6IGlhbS5JUHJpbmNpcGFsO1xuXG4gIC8qKlxuICAgKiBUaGUgU3BhcmsgVUkgbG9ncyBsb2NhdGlvbiBpZiBTcGFyayBVSSBtb25pdG9yaW5nIGFuZCBkZWJ1Z2dpbmcgaXMgZW5hYmxlZC5cbiAgICpcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZ2x1ZS9sYXRlc3QvZGcvbW9uaXRvci1zcGFyay11aS1qb2JzLmh0bWxcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZ2x1ZS9sYXRlc3QvZGcvYXdzLWdsdWUtcHJvZ3JhbW1pbmctZXRsLWdsdWUtYXJndW1lbnRzLmh0bWxcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBzcGFya1VJTG9nZ2luZ0xvY2F0aW9uPzogU3BhcmtVSUxvZ2dpbmdMb2NhdGlvbjtcblxuICAvKipcbiAgICogUHlTcGFya0ZsZXhFdGxKb2IgY29uc3RydWN0b3JcbiAgICovXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBQeVNwYXJrRmxleEV0bEpvYlByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkLCB7XG4gICAgICBwaHlzaWNhbE5hbWU6IHByb3BzLmpvYk5hbWUsXG4gICAgfSk7XG5cbiAgICAvLyBTZXQgdXAgcm9sZSBhbmQgcGVybWlzc2lvbnMgZm9yIHByaW5jaXBhbFxuICAgIHRoaXMucm9sZSA9IHByb3BzLnJvbGUsIHtcbiAgICAgIGFzc3VtZWRCeTogbmV3IGlhbS5TZXJ2aWNlUHJpbmNpcGFsKCdnbHVlLmFtYXpvbmF3cy5jb20nKSxcbiAgICAgIG1hbmFnZWRQb2xpY2llczogW2lhbS5NYW5hZ2VkUG9saWN5LmZyb21Bd3NNYW5hZ2VkUG9saWN5TmFtZSgnc2VydmljZS1yb2xlL0FXU0dsdWVTZXJ2aWNlUm9sZScpXSxcbiAgICB9O1xuICAgIHRoaXMuZ3JhbnRQcmluY2lwYWwgPSB0aGlzLnJvbGU7XG5cbiAgICAvLyBFbmFibGUgU3BhcmtVSSBieSBkZWZhdWx0IGFzIGEgYmVzdCBwcmFjdGljZVxuICAgIGNvbnN0IHNwYXJrVUlBcmdzID0gcHJvcHMuc3BhcmtVST8uYnVja2V0ID8gdGhpcy5zZXR1cFNwYXJrVUkodGhpcy5yb2xlLCBwcm9wcy5zcGFya1VJKSA6IHVuZGVmaW5lZDtcbiAgICB0aGlzLnNwYXJrVUlMb2dnaW5nTG9jYXRpb24gPSBzcGFya1VJQXJncz8ubG9jYXRpb247XG5cbiAgICAvLyBFbmFibGUgQ2xvdWRXYXRjaCBtZXRyaWNzIGFuZCBjb250aW51b3VzIGxvZ2dpbmcgYnkgZGVmYXVsdCBhcyBhIGJlc3QgcHJhY3RpY2VcbiAgICBjb25zdCBjb250aW51b3VzTG9nZ2luZ0FyZ3MgPSB0aGlzLnNldHVwQ29udGludW91c0xvZ2dpbmcodGhpcy5yb2xlLCBwcm9wcy5jb250aW51b3VzTG9nZ2luZyk7XG4gICAgY29uc3QgcHJvZmlsaW5nTWV0cmljc0FyZ3MgPSB7ICctLWVuYWJsZS1tZXRyaWNzJzogJycgfTtcbiAgICBjb25zdCBvYnNlcnZhYmlsaXR5TWV0cmljc0FyZ3MgPSB7ICctLWVuYWJsZS1vYnNlcnZhYmlsaXR5LW1ldHJpY3MnOiAndHJ1ZScgfTtcblxuICAgIC8vIEdhdGhlciBleGVjdXRhYmxlIGFyZ3VtZW50c1xuICAgIGNvbnN0IGV4ZWN1YXRibGVBcmdzID0gdGhpcy5leGVjdXRhYmxlQXJndW1lbnRzKHByb3BzKTtcblxuICAgIC8vIENvbmJpbmUgY29tbWFuZCBsaW5lIGFyZ3VtZW50cyBpbnRvIGEgc2luZ2xlIGxpbmUgaXRlbVxuICAgIGNvbnN0IGRlZmF1bHRBcmd1bWVudHMgPSB7XG4gICAgICAuLi5leGVjdWF0YmxlQXJncyxcbiAgICAgIC4uLmNvbnRpbnVvdXNMb2dnaW5nQXJncyxcbiAgICAgIC4uLnByb2ZpbGluZ01ldHJpY3NBcmdzLFxuICAgICAgLi4ub2JzZXJ2YWJpbGl0eU1ldHJpY3NBcmdzLFxuICAgICAgLi4uc3BhcmtVSUFyZ3M/LmFyZ3MsXG4gICAgICAuLi50aGlzLmNoZWNrTm9SZXNlcnZlZEFyZ3MocHJvcHMuZGVmYXVsdEFyZ3VtZW50cyksXG4gICAgfTtcblxuICAgIGNvbnN0IGpvYlJlc291cmNlID0gbmV3IENmbkpvYih0aGlzLCAnUmVzb3VyY2UnLCB7XG4gICAgICBuYW1lOiBwcm9wcy5qb2JOYW1lLFxuICAgICAgZGVzY3JpcHRpb246IHByb3BzLmRlc2NyaXB0aW9uLFxuICAgICAgcm9sZTogdGhpcy5yb2xlLnJvbGVBcm4sXG4gICAgICBjb21tYW5kOiB7XG4gICAgICAgIG5hbWU6IEpvYlR5cGUuRVRMLFxuICAgICAgICBzY3JpcHRMb2NhdGlvbjogdGhpcy5jb2RlUzNPYmplY3RVcmwocHJvcHMuc2NyaXB0KSxcbiAgICAgICAgcHl0aG9uVmVyc2lvbjogUHl0aG9uVmVyc2lvbi5USFJFRSxcbiAgICAgIH0sXG4gICAgICBnbHVlVmVyc2lvbjogcHJvcHMuZ2x1ZVZlcnNpb24gPyBwcm9wcy5nbHVlVmVyc2lvbiA6IEdsdWVWZXJzaW9uLlYzXzAsXG4gICAgICB3b3JrZXJUeXBlOiBwcm9wcy53b3JrZXJUeXBlID8gcHJvcHMud29ya2VyVHlwZSA6IFdvcmtlclR5cGUuR18xWCxcbiAgICAgIG51bWJlck9mV29ya2VyczogcHJvcHMubnVtYmVyT2ZXb3JrZXJzID8gcHJvcHMubnVtYmVyT2ZXb3JrZXJzIDogMTAsXG4gICAgICBtYXhSZXRyaWVzOiBwcm9wcy5tYXhSZXRyaWVzLFxuICAgICAgZXhlY3V0aW9uUHJvcGVydHk6IHByb3BzLm1heENvbmN1cnJlbnRSdW5zID8geyBtYXhDb25jdXJyZW50UnVuczogcHJvcHMubWF4Q29uY3VycmVudFJ1bnMgfSA6IHVuZGVmaW5lZCxcbiAgICAgIG5vdGlmaWNhdGlvblByb3BlcnR5OiBwcm9wcy5ub3RpZnlEZWxheUFmdGVyID8geyBub3RpZnlEZWxheUFmdGVyOiBwcm9wcy5ub3RpZnlEZWxheUFmdGVyLnRvTWludXRlcygpIH0gOiB1bmRlZmluZWQsXG4gICAgICB0aW1lb3V0OiBwcm9wcy50aW1lb3V0Py50b01pbnV0ZXMoKSxcbiAgICAgIGNvbm5lY3Rpb25zOiBwcm9wcy5jb25uZWN0aW9ucyA/IHsgY29ubmVjdGlvbnM6IHByb3BzLmNvbm5lY3Rpb25zLm1hcCgoY29ubmVjdGlvbikgPT4gY29ubmVjdGlvbi5jb25uZWN0aW9uTmFtZSkgfSA6IHVuZGVmaW5lZCxcbiAgICAgIHNlY3VyaXR5Q29uZmlndXJhdGlvbjogcHJvcHMuc2VjdXJpdHlDb25maWd1cmF0aW9uPy5zZWN1cml0eUNvbmZpZ3VyYXRpb25OYW1lLFxuICAgICAgdGFnczogcHJvcHMudGFncyxcbiAgICAgIGV4ZWN1dGlvbkNsYXNzOiBFeGVjdXRpb25DbGFzcy5GTEVYLFxuICAgICAgam9iUnVuUXVldWluZ0VuYWJsZWQ6IGZhbHNlLFxuICAgICAgZGVmYXVsdEFyZ3VtZW50cyxcblxuICAgIH0pO1xuXG4gICAgY29uc3QgcmVzb3VyY2VOYW1lID0gdGhpcy5nZXRSZXNvdXJjZU5hbWVBdHRyaWJ1dGUoam9iUmVzb3VyY2UucmVmKTtcbiAgICB0aGlzLmpvYkFybiA9IHRoaXMuYnVpbGRKb2JBcm4odGhpcywgcmVzb3VyY2VOYW1lKTtcbiAgICB0aGlzLmpvYk5hbWUgPSByZXNvdXJjZU5hbWU7XG4gIH1cblxuICAvKipcbiAgICpTZXQgdGhlIGV4ZWN1dGFibGUgYXJndW1lbnRzIHdpdGggYmVzdCBwcmFjdGljZXMgZW5hYmxlZCBieSBkZWZhdWx0XG4gICAqXG4gICAqIEByZXR1cm5zIEFuIGFycmF5IG9mIGFyZ3VtZW50cyBmb3IgR2x1ZSB0byB1c2Ugb24gZXhlY3V0aW9uXG4gICAqL1xuICBwcml2YXRlIGV4ZWN1dGFibGVBcmd1bWVudHMocHJvcHM6IFB5U3BhcmtGbGV4RXRsSm9iUHJvcHMpIHtcbiAgICBjb25zdCBhcmdzOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9ID0ge307XG4gICAgYXJnc1snLS1qb2ItbGFuZ3VhZ2UnXSA9IEpvYkxhbmd1YWdlLlBZVEhPTjtcblxuICAgIGlmIChwcm9wcy5leHRyYVB5dGhvbkZpbGVzICYmIHByb3BzLmV4dHJhUHl0aG9uRmlsZXMubGVuZ3RoID4gMCkge1xuICAgICAgYXJnc1snLS1leHRyYS1weS1maWxlcyddID0gcHJvcHMuZXh0cmFQeXRob25GaWxlcy5tYXAoY29kZSA9PiB0aGlzLmNvZGVTM09iamVjdFVybChjb2RlKSkuam9pbignLCcpO1xuICAgIH1cbiAgICBpZiAocHJvcHMuZXh0cmFGaWxlcyAmJiBwcm9wcy5leHRyYUZpbGVzLmxlbmd0aCA+IDApIHtcbiAgICAgIGFyZ3NbJy0tZXh0cmEtZmlsZXMnXSA9IHByb3BzLmV4dHJhRmlsZXMubWFwKGNvZGUgPT4gdGhpcy5jb2RlUzNPYmplY3RVcmwoY29kZSkpLmpvaW4oJywnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXJncztcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgdGhlIGFyZ3VtZW50cyBmb3Igc3BhcmtVSSB3aXRoIGJlc3QgcHJhY3RpY2VzIGVuYWJsZWQgYnkgZGVmYXVsdFxuICAgKlxuICAgKiBAcmV0dXJucyBBbiBhcnJheSBvZiBhcmd1bWVudHMgZm9yIGVuYWJsaW5nIHNwYXJrVUlcbiAgICovXG5cbiAgcHJpdmF0ZSBzZXR1cFNwYXJrVUkocm9sZTogaWFtLklSb2xlLCBzcGFya1VpUHJvcHM6IFNwYXJrVUlQcm9wcykge1xuXG4gICAgdmFsaWRhdGVTcGFya1VpUHJlZml4KHNwYXJrVWlQcm9wcy5wcmVmaXgpO1xuICAgIGNvbnN0IGJ1Y2tldCA9IHNwYXJrVWlQcm9wcy5idWNrZXQgPz8gbmV3IEJ1Y2tldCh0aGlzLCAnU3BhcmtVSUJ1Y2tldCcsIHsgZW5mb3JjZVNTTDogdHJ1ZSwgZW5jcnlwdGlvbjogQnVja2V0RW5jcnlwdGlvbi5TM19NQU5BR0VEIH0pO1xuICAgIGJ1Y2tldC5ncmFudFJlYWRXcml0ZShyb2xlLCBjbGVhblNwYXJrVWlQcmVmaXhGb3JHcmFudChzcGFya1VpUHJvcHMucHJlZml4KSk7XG4gICAgY29uc3QgYXJncyA9IHtcbiAgICAgICctLWVuYWJsZS1zcGFyay11aSc6ICd0cnVlJyxcbiAgICAgICctLXNwYXJrLWV2ZW50LWxvZ3MtcGF0aCc6IGJ1Y2tldC5zM1VybEZvck9iamVjdChzcGFya1VpUHJvcHMucHJlZml4KS5yZXBsYWNlKC9cXC8/JC8sICcvJyksIC8vIHBhdGggd2lsbCBhbHdheXMgZW5kIHdpdGggYSBzbGFzaFxuICAgIH07XG5cbiAgICByZXR1cm4ge1xuICAgICAgbG9jYXRpb246IHtcbiAgICAgICAgcHJlZml4OiBzcGFya1VpUHJvcHMucHJlZml4LFxuICAgICAgICBidWNrZXQsXG4gICAgICB9LFxuICAgICAgYXJncyxcbiAgICB9O1xuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import * as iam from 'aws-cdk-lib/aws-iam';
|
|
2
|
+
import { Job, JobProperties } from './job';
|
|
3
|
+
import { Construct } from 'constructs';
|
|
4
|
+
import { SparkUIProps, SparkUILoggingLocation } from './spark-ui-utils';
|
|
5
|
+
import { Code } from '../code';
|
|
6
|
+
/**
|
|
7
|
+
* Properties for creating a Python Spark ETL job
|
|
8
|
+
*/
|
|
9
|
+
export interface PySparkStreamingJobProps extends JobProperties {
|
|
10
|
+
/**
|
|
11
|
+
* Enables the Spark UI debugging and monitoring with the specified props.
|
|
12
|
+
*
|
|
13
|
+
* @default - Spark UI debugging and monitoring is disabled.
|
|
14
|
+
*
|
|
15
|
+
* @see https://docs.aws.amazon.com/glue/latest/dg/monitor-spark-ui-jobs.html
|
|
16
|
+
* @see https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-glue-arguments.html
|
|
17
|
+
*/
|
|
18
|
+
readonly sparkUI?: SparkUIProps;
|
|
19
|
+
/**
|
|
20
|
+
* Extra Python Files S3 URL (optional)
|
|
21
|
+
* S3 URL where additional python dependencies are located
|
|
22
|
+
*
|
|
23
|
+
* @default - no extra files
|
|
24
|
+
*/
|
|
25
|
+
readonly extraPythonFiles?: Code[];
|
|
26
|
+
/**
|
|
27
|
+
* Additional files, such as configuration files that AWS Glue copies to the working directory of your script before executing it.
|
|
28
|
+
*
|
|
29
|
+
* @default - no extra files specified.
|
|
30
|
+
*
|
|
31
|
+
* @see https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-glue-arguments.html
|
|
32
|
+
*/
|
|
33
|
+
readonly extraFiles?: Code[];
|
|
34
|
+
/**
|
|
35
|
+
* Specifies whether job run queuing is enabled for the job runs for this job.
|
|
36
|
+
* A value of true means job run queuing is enabled for the job runs.
|
|
37
|
+
* If false or not populated, the job runs will not be considered for queueing.
|
|
38
|
+
* If this field does not match the value set in the job run, then the value from
|
|
39
|
+
* the job run field will be used. This property must be set to false for flex jobs.
|
|
40
|
+
* If this property is enabled, maxRetries must be set to zero.
|
|
41
|
+
*
|
|
42
|
+
* @default - no job run queuing
|
|
43
|
+
*/
|
|
44
|
+
readonly jobRunQueuingEnabled?: boolean;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Python Spark Streaming Jobs class
|
|
48
|
+
*
|
|
49
|
+
* A Streaming job is similar to an ETL job, except that it performs ETL on data streams
|
|
50
|
+
* using the Apache Spark Structured Streaming framework.
|
|
51
|
+
* These jobs will default to use Python 3.9.
|
|
52
|
+
*
|
|
53
|
+
* Similar to ETL jobs, streaming job supports Scala and Python languages. Similar to ETL,
|
|
54
|
+
* it supports G1 and G2 worker type and 2.0, 3.0 and 4.0 version. We’ll default to G2 worker
|
|
55
|
+
* and 4.0 version for streaming jobs which developers can override.
|
|
56
|
+
* We will enable —enable-metrics, —enable-spark-ui, —enable-continuous-cloudwatch-log.
|
|
57
|
+
*/
|
|
58
|
+
export declare class PySparkStreamingJob extends Job {
|
|
59
|
+
readonly jobArn: string;
|
|
60
|
+
readonly jobName: string;
|
|
61
|
+
readonly role: iam.IRole;
|
|
62
|
+
readonly grantPrincipal: iam.IPrincipal;
|
|
63
|
+
/**
|
|
64
|
+
* The Spark UI logs location if Spark UI monitoring and debugging is enabled.
|
|
65
|
+
*
|
|
66
|
+
* @see https://docs.aws.amazon.com/glue/latest/dg/monitor-spark-ui-jobs.html
|
|
67
|
+
* @see https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-glue-arguments.html
|
|
68
|
+
*/
|
|
69
|
+
readonly sparkUILoggingLocation?: SparkUILoggingLocation;
|
|
70
|
+
/**
|
|
71
|
+
* PySparkStreamingJob constructor
|
|
72
|
+
*/
|
|
73
|
+
constructor(scope: Construct, id: string, props: PySparkStreamingJobProps);
|
|
74
|
+
/**
|
|
75
|
+
* Set the executable arguments with best practices enabled by default
|
|
76
|
+
*
|
|
77
|
+
* @param props
|
|
78
|
+
* @returns An array of arguments for Glue to use on execution
|
|
79
|
+
*/
|
|
80
|
+
private executableArguments;
|
|
81
|
+
private setupSparkUI;
|
|
82
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.PySparkStreamingJob = void 0;
|
|
5
|
+
const jsiiDeprecationWarnings = require("../../.warnings.jsii.js");
|
|
6
|
+
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
|
7
|
+
const aws_glue_1 = require("aws-cdk-lib/aws-glue");
|
|
8
|
+
const iam = require("aws-cdk-lib/aws-iam");
|
|
9
|
+
const aws_s3_1 = require("aws-cdk-lib/aws-s3");
|
|
10
|
+
const job_1 = require("./job");
|
|
11
|
+
const constants_1 = require("../constants");
|
|
12
|
+
const spark_ui_utils_1 = require("./spark-ui-utils");
|
|
13
|
+
/**
|
|
14
|
+
* Python Spark Streaming Jobs class
|
|
15
|
+
*
|
|
16
|
+
* A Streaming job is similar to an ETL job, except that it performs ETL on data streams
|
|
17
|
+
* using the Apache Spark Structured Streaming framework.
|
|
18
|
+
* These jobs will default to use Python 3.9.
|
|
19
|
+
*
|
|
20
|
+
* Similar to ETL jobs, streaming job supports Scala and Python languages. Similar to ETL,
|
|
21
|
+
* it supports G1 and G2 worker type and 2.0, 3.0 and 4.0 version. We’ll default to G2 worker
|
|
22
|
+
* and 4.0 version for streaming jobs which developers can override.
|
|
23
|
+
* We will enable —enable-metrics, —enable-spark-ui, —enable-continuous-cloudwatch-log.
|
|
24
|
+
*/
|
|
25
|
+
class PySparkStreamingJob extends job_1.Job {
|
|
26
|
+
/**
|
|
27
|
+
* PySparkStreamingJob constructor
|
|
28
|
+
*/
|
|
29
|
+
constructor(scope, id, props) {
|
|
30
|
+
super(scope, id, {
|
|
31
|
+
physicalName: props.jobName,
|
|
32
|
+
});
|
|
33
|
+
try {
|
|
34
|
+
jsiiDeprecationWarnings._aws_cdk_aws_glue_alpha_PySparkStreamingJobProps(props);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
|
38
|
+
Error.captureStackTrace(error, PySparkStreamingJob);
|
|
39
|
+
}
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
42
|
+
// Set up role and permissions for principal
|
|
43
|
+
this.role = props.role, {
|
|
44
|
+
assumedBy: new iam.ServicePrincipal('glue.amazonaws.com'),
|
|
45
|
+
managedPolicies: [iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSGlueServiceRole')],
|
|
46
|
+
};
|
|
47
|
+
this.grantPrincipal = this.role;
|
|
48
|
+
// Enable SparkUI by default as a best practice
|
|
49
|
+
const sparkUIArgs = props.sparkUI?.bucket ? this.setupSparkUI(this.role, props.sparkUI) : undefined;
|
|
50
|
+
this.sparkUILoggingLocation = sparkUIArgs?.location;
|
|
51
|
+
// Enable CloudWatch metrics and continuous logging by default as a best practice
|
|
52
|
+
const continuousLoggingArgs = this.setupContinuousLogging(this.role, props.continuousLogging);
|
|
53
|
+
const profilingMetricsArgs = { '--enable-metrics': '' };
|
|
54
|
+
const observabilityMetricsArgs = { '--enable-observability-metrics': 'true' };
|
|
55
|
+
// Gather executable arguments
|
|
56
|
+
const executableArgs = this.executableArguments(props);
|
|
57
|
+
// Conbine command line arguments into a single line item
|
|
58
|
+
const defaultArguments = {
|
|
59
|
+
...executableArgs,
|
|
60
|
+
...continuousLoggingArgs,
|
|
61
|
+
...profilingMetricsArgs,
|
|
62
|
+
...observabilityMetricsArgs,
|
|
63
|
+
...sparkUIArgs?.args,
|
|
64
|
+
...this.checkNoReservedArgs(props.defaultArguments),
|
|
65
|
+
};
|
|
66
|
+
const jobResource = new aws_glue_1.CfnJob(this, 'Resource', {
|
|
67
|
+
name: props.jobName,
|
|
68
|
+
description: props.description,
|
|
69
|
+
role: this.role.roleArn,
|
|
70
|
+
command: {
|
|
71
|
+
name: constants_1.JobType.STREAMING,
|
|
72
|
+
scriptLocation: this.codeS3ObjectUrl(props.script),
|
|
73
|
+
pythonVersion: constants_1.PythonVersion.THREE,
|
|
74
|
+
},
|
|
75
|
+
glueVersion: props.glueVersion ? props.glueVersion : constants_1.GlueVersion.V4_0,
|
|
76
|
+
workerType: props.workerType ? props.workerType : constants_1.WorkerType.G_1X,
|
|
77
|
+
numberOfWorkers: props.numberOfWorkers ? props.numberOfWorkers : 10,
|
|
78
|
+
maxRetries: props.jobRunQueuingEnabled ? 0 : props.maxRetries,
|
|
79
|
+
jobRunQueuingEnabled: props.jobRunQueuingEnabled ? props.jobRunQueuingEnabled : false,
|
|
80
|
+
executionProperty: props.maxConcurrentRuns ? { maxConcurrentRuns: props.maxConcurrentRuns } : undefined,
|
|
81
|
+
timeout: props.timeout?.toMinutes(),
|
|
82
|
+
connections: props.connections ? { connections: props.connections.map((connection) => connection.connectionName) } : undefined,
|
|
83
|
+
securityConfiguration: props.securityConfiguration?.securityConfigurationName,
|
|
84
|
+
tags: props.tags,
|
|
85
|
+
defaultArguments,
|
|
86
|
+
});
|
|
87
|
+
const resourceName = this.getResourceNameAttribute(jobResource.ref);
|
|
88
|
+
this.jobArn = this.buildJobArn(this, resourceName);
|
|
89
|
+
this.jobName = resourceName;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Set the executable arguments with best practices enabled by default
|
|
93
|
+
*
|
|
94
|
+
* @param props
|
|
95
|
+
* @returns An array of arguments for Glue to use on execution
|
|
96
|
+
*/
|
|
97
|
+
executableArguments(props) {
|
|
98
|
+
const args = {};
|
|
99
|
+
args['--job-language'] = constants_1.JobLanguage.PYTHON;
|
|
100
|
+
if (props.extraPythonFiles && props.extraPythonFiles.length > 0) {
|
|
101
|
+
args['--extra-py-files'] = props.extraPythonFiles.map(code => this.codeS3ObjectUrl(code)).join(',');
|
|
102
|
+
}
|
|
103
|
+
if (props.extraFiles && props.extraFiles.length > 0) {
|
|
104
|
+
args['--extra-files'] = props.extraFiles.map(code => this.codeS3ObjectUrl(code)).join(',');
|
|
105
|
+
}
|
|
106
|
+
return args;
|
|
107
|
+
}
|
|
108
|
+
setupSparkUI(role, sparkUiProps) {
|
|
109
|
+
(0, spark_ui_utils_1.validateSparkUiPrefix)(sparkUiProps.prefix);
|
|
110
|
+
const bucket = sparkUiProps.bucket ?? new aws_s3_1.Bucket(this, 'SparkUIBucket', { enforceSSL: true, encryption: aws_s3_1.BucketEncryption.S3_MANAGED });
|
|
111
|
+
bucket.grantReadWrite(role, (0, spark_ui_utils_1.cleanSparkUiPrefixForGrant)(sparkUiProps.prefix));
|
|
112
|
+
const args = {
|
|
113
|
+
'--enable-spark-ui': 'true',
|
|
114
|
+
'--spark-event-logs-path': bucket.s3UrlForObject(sparkUiProps.prefix).replace(/\/?$/, '/'), // path will always end with a slash
|
|
115
|
+
};
|
|
116
|
+
return {
|
|
117
|
+
location: {
|
|
118
|
+
prefix: sparkUiProps.prefix,
|
|
119
|
+
bucket,
|
|
120
|
+
},
|
|
121
|
+
args,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
exports.PySparkStreamingJob = PySparkStreamingJob;
|
|
126
|
+
_a = JSII_RTTI_SYMBOL_1;
|
|
127
|
+
PySparkStreamingJob[_a] = { fqn: "@aws-cdk/aws-glue-alpha.PySparkStreamingJob", version: "2.177.0-alpha.0" };
|
|
128
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHlzcGFyay1zdHJlYW1pbmctam9iLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsicHlzcGFyay1zdHJlYW1pbmctam9iLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLG1EQUE4QztBQUM5QywyQ0FBMkM7QUFDM0MsK0NBQThEO0FBQzlELCtCQUEyQztBQUUzQyw0Q0FBNEY7QUFDNUYscURBQTJIO0FBK0MzSDs7Ozs7Ozs7Ozs7R0FXRztBQUNILE1BQWEsbUJBQW9CLFNBQVEsU0FBRztJQWMxQzs7T0FFRztJQUNILFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBK0I7UUFDdkUsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUU7WUFDZixZQUFZLEVBQUUsS0FBSyxDQUFDLE9BQU87U0FDNUIsQ0FBQyxDQUFDOzs7Ozs7K0NBcEJNLG1CQUFtQjs7OztRQXNCNUIsNENBQTRDO1FBQzVDLElBQUksQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDLElBQUksRUFBRTtZQUN0QixTQUFTLEVBQUUsSUFBSSxHQUFHLENBQUMsZ0JBQWdCLENBQUMsb0JBQW9CLENBQUM7WUFDekQsZUFBZSxFQUFFLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyx3QkFBd0IsQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO1NBQ2pHLENBQUM7UUFDRixJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7UUFFaEMsK0NBQStDO1FBQy9DLE1BQU0sV0FBVyxHQUFHLEtBQUssQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7UUFDcEcsSUFBSSxDQUFDLHNCQUFzQixHQUFHLFdBQVcsRUFBRSxRQUFRLENBQUM7UUFFcEQsaUZBQWlGO1FBQ2pGLE1BQU0scUJBQXFCLEdBQUcsSUFBSSxD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QUMsQ0FBQztRQUM3RSxNQUFNLElBQUksR0FBRztZQUNYLG1CQUFtQixFQUFFLE1BQU07WUFDM0IseUJBQXlCLEVBQUUsTUFBTSxDQUFDLGNBQWMsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsRUFBRSxvQ0FBb0M7U0FDakksQ0FBQztRQUVGLE9BQU87WUFDTCxRQUFRLEVBQUU7Z0JBQ1IsTUFBTSxFQUFFLFlBQVksQ0FBQyxNQUFNO2dCQUMzQixNQUFNO2FBQ1A7WUFDRCxJQUFJO1NBQ0wsQ0FBQztLQUNIOztBQWxISCxrREFtSEMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDZm5Kb2IgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZ2x1ZSc7XG5pbXBvcnQgKiBhcyBpYW0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWlhbSc7XG5pbXBvcnQgeyBCdWNrZXQsIEJ1Y2tldEVuY3J5cHRpb24gfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtczMnO1xuaW1wb3J0IHsgSm9iLCBKb2JQcm9wZXJ0aWVzIH0gZnJvbSAnLi9qb2InO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgeyBKb2JUeXBlLCBHbHVlVmVyc2lvbiwgSm9iTGFuZ3VhZ2UsIFB5dGhvblZlcnNpb24sIFdvcmtlclR5cGUgfSBmcm9tICcuLi9jb25zdGFudHMnO1xuaW1wb3J0IHsgU3BhcmtVSVByb3BzLCBTcGFya1VJTG9nZ2luZ0xvY2F0aW9uLCB2YWxpZGF0ZVNwYXJrVWlQcmVmaXgsIGNsZWFuU3BhcmtVaVByZWZpeEZvckdyYW50IH0gZnJvbSAnLi9zcGFyay11aS11dGlscyc7XG5pbXBvcnQgeyBDb2RlIH0gZnJvbSAnLi4vY29kZSc7XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgY3JlYXRpbmcgYSBQeXRob24gU3BhcmsgRVRMIGpvYlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFB5U3BhcmtTdHJlYW1pbmdKb2JQcm9wcyBleHRlbmRzIEpvYlByb3BlcnRpZXMge1xuICAvKipcbiAgICogRW5hYmxlcyB0aGUgU3BhcmsgVUkgZGVidWdnaW5nIGFuZCBtb25pdG9yaW5nIHdpdGggdGhlIHNwZWNpZmllZCBwcm9wcy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBTcGFyayBVSSBkZWJ1Z2dpbmcgYW5kIG1vbml0b3JpbmcgaXMgZGlzYWJsZWQuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2dsdWUvbGF0ZXN0L2RnL21vbml0b3Itc3BhcmstdWktam9icy5odG1sXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2dsdWUvbGF0ZXN0L2RnL2F3cy1nbHVlLXByb2dyYW1taW5nLWV0bC1nbHVlLWFyZ3VtZW50cy5odG1sXG4gICAqL1xuICByZWFkb25seSBzcGFya1VJPzogU3BhcmtVSVByb3BzO1xuXG4gIC8qKlxuICAgKiBFeHRyYSBQeXRob24gRmlsZXMgUzMgVVJMIChvcHRpb25hbClcbiAgICogUzMgVVJMIHdoZXJlIGFkZGl0aW9uYWwgcHl0aG9uIGRlcGVuZGVuY2llcyBhcmUgbG9jYXRlZFxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIGV4dHJhIGZpbGVzXG4gICAqL1xuICByZWFkb25seSBleHRyYVB5dGhvbkZpbGVzPzogQ29kZVtdO1xuXG4gIC8qKlxuICAgKiBBZGRpdGlvbmFsIGZpbGVzLCBzdWNoIGFzIGNvbmZpZ3VyYXRpb24gZmlsZXMgdGhhdCBBV1MgR2x1ZSBjb3BpZXMgdG8gdGhlIHdvcmtpbmcgZGlyZWN0b3J5IG9mIHlvdXIgc2NyaXB0IGJlZm9yZSBleGVjdXRpbmcgaXQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gZXh0cmEgZmlsZXMgc3BlY2lmaWVkLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9nbHVlL2xhdGVzdC9kZy9hd3MtZ2x1ZS1wcm9ncmFtbWluZy1ldGwtZ2x1ZS1hcmd1bWVudHMuaHRtbFxuICAgKi9cbiAgcmVhZG9ubHkgZXh0cmFGaWxlcz86IENvZGVbXTtcblxuICAvKipcbiAgICogU3BlY2lmaWVzIHdoZXRoZXIgam9iIHJ1biBxdWV1aW5nIGlzIGVuYWJsZWQgZm9yIHRoZSBqb2IgcnVucyBmb3IgdGhpcyBqb2IuXG4gICAqIEEgdmFsdWUgb2YgdHJ1ZSBtZWFucyBqb2IgcnVuIHF1ZXVpbmcgaXMgZW5hYmxlZCBmb3IgdGhlIGpvYiBydW5zLlxuICAgKiBJZiBmYWxzZSBvciBub3QgcG9wdWxhdGVkLCB0aGUgam9iIHJ1bnMgd2lsbCBub3QgYmUgY29uc2lkZXJlZCBmb3IgcXVldWVpbmcuXG4gICAqIElmIHRoaXMgZmllbGQgZG9lcyBub3QgbWF0Y2ggdGhlIHZhbHVlIHNldCBpbiB0aGUgam9iIHJ1biwgdGhlbiB0aGUgdmFsdWUgZnJvbVxuICAgKiB0aGUgam9iIHJ1biBmaWVsZCB3aWxsIGJlIHVzZWQuIFRoaXMgcHJvcGVydHkgbXVzdCBiZSBzZXQgdG8gZmFsc2UgZm9yIGZsZXggam9icy5cbiAgICogSWYgdGhpcyBwcm9wZXJ0eSBpcyBlbmFibGVkLCBtYXhSZXRyaWVzIG11c3QgYmUgc2V0IHRvIHplcm8uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gam9iIHJ1biBxdWV1aW5nXG4gICAqL1xuICByZWFkb25seSBqb2JSdW5RdWV1aW5nRW5hYmxlZD86IGJvb2xlYW47XG59XG5cbi8qKlxuICogUHl0aG9uIFNwYXJrIFN0cmVhbWluZyBKb2JzIGNsYXNzXG4gKlxuICogQSBTdHJlYW1pbmcgam9iIGlzIHNpbWlsYXIgdG8gYW4gRVRMIGpvYiwgZXhjZXB0IHRoYXQgaXQgcGVyZm9ybXMgRVRMIG9uIGRhdGEgc3RyZWFtc1xuICogdXNpbmcgdGhlIEFwYWNoZSBTcGFyayBTdHJ1Y3R1cmVkIFN0cmVhbWluZyBmcmFtZXdvcmsuXG4gKiBUaGVzZSBqb2JzIHdpbGwgZGVmYXVsdCB0byB1c2UgUHl0aG9uIDMuOS5cbiAqXG4gKiBTaW1pbGFyIHRvIEVUTCBqb2JzLCBzdHJlYW1pbmcgam9iIHN1cHBvcnRzIFNjYWxhIGFuZCBQeXRob24gbGFuZ3VhZ2VzLiBTaW1pbGFyIHRvIEVUTCxcbiAqIGl0IHN1cHBvcnRzIEcxIGFuZCBHMiB3b3JrZXIgdHlwZSBhbmQgMi4wLCAzLjAgYW5kIDQuMCB2ZXJzaW9uLiBXZeKAmWxsIGRlZmF1bHQgdG8gRzIgd29ya2VyXG4gKiBhbmQgNC4wIHZlcnNpb24gZm9yIHN0cmVhbWluZyBqb2JzIHdoaWNoIGRldmVsb3BlcnMgY2FuIG92ZXJyaWRlLlxuICogV2Ugd2lsbCBlbmFibGUg4oCUZW5hYmxlLW1ldHJpY3MsIOKAlGVuYWJsZS1zcGFyay11aSwg4oCUZW5hYmxlLWNvbnRpbnVvdXMtY2xvdWR3YXRjaC1sb2cuXG4gKi9cbmV4cG9ydCBjbGFzcyBQeVNwYXJrU3RyZWFtaW5nSm9iIGV4dGVuZHMgSm9iIHtcbiAgcHVibGljIHJlYWRvbmx5IGpvYkFybjogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgam9iTmFtZTogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgcm9sZTogaWFtLklSb2xlO1xuICBwdWJsaWMgcmVhZG9ubHkgZ3JhbnRQcmluY2lwYWw6IGlhbS5JUHJpbmNpcGFsO1xuXG4gIC8qKlxuICAgKiBUaGUgU3BhcmsgVUkgbG9ncyBsb2NhdGlvbiBpZiBTcGFyayBVSSBtb25pdG9yaW5nIGFuZCBkZWJ1Z2dpbmcgaXMgZW5hYmxlZC5cbiAgICpcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZ2x1ZS9sYXRlc3QvZGcvbW9uaXRvci1zcGFyay11aS1qb2JzLmh0bWxcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZ2x1ZS9sYXRlc3QvZGcvYXdzLWdsdWUtcHJvZ3JhbW1pbmctZXRsLWdsdWUtYXJndW1lbnRzLmh0bWxcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBzcGFya1VJTG9nZ2luZ0xvY2F0aW9uPzogU3BhcmtVSUxvZ2dpbmdMb2NhdGlvbjtcblxuICAvKipcbiAgICogUHlTcGFya1N0cmVhbWluZ0pvYiBjb25zdHJ1Y3RvclxuICAgKi9cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IFB5U3BhcmtTdHJlYW1pbmdKb2JQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCwge1xuICAgICAgcGh5c2ljYWxOYW1lOiBwcm9wcy5qb2JOYW1lLFxuICAgIH0pO1xuXG4gICAgLy8gU2V0IHVwIHJvbGUgYW5kIHBlcm1pc3Npb25zIGZvciBwcmluY2lwYWxcbiAgICB0aGlzLnJvbGUgPSBwcm9wcy5yb2xlLCB7XG4gICAgICBhc3N1bWVkQnk6IG5ldyBpYW0uU2VydmljZVByaW5jaXBhbCgnZ2x1ZS5hbWF6b25hd3MuY29tJyksXG4gICAgICBtYW5hZ2VkUG9saWNpZXM6IFtpYW0uTWFuYWdlZFBvbGljeS5mcm9tQXdzTWFuYWdlZFBvbGljeU5hbWUoJ3NlcnZpY2Utcm9sZS9BV1NHbHVlU2VydmljZVJvbGUnKV0sXG4gICAgfTtcbiAgICB0aGlzLmdyYW50UHJpbmNpcGFsID0gdGhpcy5yb2xlO1xuXG4gICAgLy8gRW5hYmxlIFNwYXJrVUkgYnkgZGVmYXVsdCBhcyBhIGJlc3QgcHJhY3RpY2VcbiAgICBjb25zdCBzcGFya1VJQXJncyA9IHByb3BzLnNwYXJrVUk/LmJ1Y2tldCA/IHRoaXMuc2V0dXBTcGFya1VJKHRoaXMucm9sZSwgcHJvcHMuc3BhcmtVSSkgOiB1bmRlZmluZWQ7XG4gICAgdGhpcy5zcGFya1VJTG9nZ2luZ0xvY2F0aW9uID0gc3BhcmtVSUFyZ3M/LmxvY2F0aW9uO1xuXG4gICAgLy8gRW5hYmxlIENsb3VkV2F0Y2ggbWV0cmljcyBhbmQgY29udGludW91cyBsb2dnaW5nIGJ5IGRlZmF1bHQgYXMgYSBiZXN0IHByYWN0aWNlXG4gICAgY29uc3QgY29udGludW91c0xvZ2dpbmdBcmdzID0gdGhpcy5zZXR1cENvbnRpbnVvdXNMb2dnaW5nKHRoaXMucm9sZSwgcHJvcHMuY29udGludW91c0xvZ2dpbmcpO1xuICAgIGNvbnN0IHByb2ZpbGluZ01ldHJpY3NBcmdzID0geyAnLS1lbmFibGUtbWV0cmljcyc6ICcnIH07XG4gICAgY29uc3Qgb2JzZXJ2YWJpbGl0eU1ldHJpY3NBcmdzID0geyAnLS1lbmFibGUtb2JzZXJ2YWJpbGl0eS1tZXRyaWNzJzogJ3RydWUnIH07XG5cbiAgICAvLyBHYXRoZXIgZXhlY3V0YWJsZSBhcmd1bWVudHNcbiAgICBjb25zdCBleGVjdXRhYmxlQXJncyA9IHRoaXMuZXhlY3V0YWJsZUFyZ3VtZW50cyhwcm9wcyk7XG5cbiAgICAvLyBDb25iaW5lIGNvbW1hbmQgbGluZSBhcmd1bWVudHMgaW50byBhIHNpbmdsZSBsaW5lIGl0ZW1cbiAgICBjb25zdCBkZWZhdWx0QXJndW1lbnRzID0ge1xuICAgICAgLi4uZXhlY3V0YWJsZUFyZ3MsXG4gICAgICAuLi5jb250aW51b3VzTG9nZ2luZ0FyZ3MsXG4gICAgICAuLi5wcm9maWxpbmdNZXRyaWNzQXJncyxcbiAgICAgIC4uLm9ic2VydmFiaWxpdHlNZXRyaWNzQXJncyxcbiAgICAgIC4uLnNwYXJrVUlBcmdzPy5hcmdzLFxuICAgICAgLi4udGhpcy5jaGVja05vUmVzZXJ2ZWRBcmdzKHByb3BzLmRlZmF1bHRBcmd1bWVudHMpLFxuICAgIH07XG5cbiAgICBjb25zdCBqb2JSZXNvdXJjZSA9IG5ldyBDZm5Kb2IodGhpcywgJ1Jlc291cmNlJywge1xuICAgICAgbmFtZTogcHJvcHMuam9iTmFtZSxcbiAgICAgIGRlc2NyaXB0aW9uOiBwcm9wcy5kZXNjcmlwdGlvbixcbiAgICAgIHJvbGU6IHRoaXMucm9sZS5yb2xlQXJuLFxuICAgICAgY29tbWFuZDoge1xuICAgICAgICBuYW1lOiBKb2JUeXBlLlNUUkVBTUlORyxcbiAgICAgICAgc2NyaXB0TG9jYXRpb246IHRoaXMuY29kZVMzT2JqZWN0VXJsKHByb3BzLnNjcmlwdCksXG4gICAgICAgIHB5dGhvblZlcnNpb246IFB5dGhvblZlcnNpb24uVEhSRUUsXG4gICAgICB9LFxuICAgICAgZ2x1ZVZlcnNpb246IHByb3BzLmdsdWVWZXJzaW9uID8gcHJvcHMuZ2x1ZVZlcnNpb24gOiBHbHVlVmVyc2lvbi5WNF8wLFxuICAgICAgd29ya2VyVHlwZTogcHJvcHMud29ya2VyVHlwZSA/IHByb3BzLndvcmtlclR5cGUgOiBXb3JrZXJUeXBlLkdfMVgsXG4gICAgICBudW1iZXJPZldvcmtlcnM6IHByb3BzLm51bWJlck9mV29ya2VycyA/IHByb3BzLm51bWJlck9mV29ya2VycyA6IDEwLFxuICAgICAgbWF4UmV0cmllczogcHJvcHMuam9iUnVuUXVldWluZ0VuYWJsZWQgPyAwIDogcHJvcHMubWF4UmV0cmllcyxcbiAgICAgIGpvYlJ1blF1ZXVpbmdFbmFibGVkOiBwcm9wcy5qb2JSdW5RdWV1aW5nRW5hYmxlZCA/IHByb3BzLmpvYlJ1blF1ZXVpbmdFbmFibGVkIDogZmFsc2UsXG4gICAgICBleGVjdXRpb25Qcm9wZXJ0eTogcHJvcHMubWF4Q29uY3VycmVudFJ1bnMgPyB7IG1heENvbmN1cnJlbnRSdW5zOiBwcm9wcy5tYXhDb25jdXJyZW50UnVucyB9IDogdW5kZWZpbmVkLFxuICAgICAgdGltZW91dDogcHJvcHMudGltZW91dD8udG9NaW51dGVzKCksXG4gICAgICBjb25uZWN0aW9uczogcHJvcHMuY29ubmVjdGlvbnMgPyB7IGNvbm5lY3Rpb25zOiBwcm9wcy5jb25uZWN0aW9ucy5tYXAoKGNvbm5lY3Rpb24pID0+IGNvbm5lY3Rpb24uY29ubmVjdGlvbk5hbWUpIH0gOiB1bmRlZmluZWQsXG4gICAgICBzZWN1cml0eUNvbmZpZ3VyYXRpb246IHByb3BzLnNlY3VyaXR5Q29uZmlndXJhdGlvbj8uc2VjdXJpdHlDb25maWd1cmF0aW9uTmFtZSxcbiAgICAgIHRhZ3M6IHByb3BzLnRhZ3MsXG4gICAgICBkZWZhdWx0QXJndW1lbnRzLFxuICAgIH0pO1xuXG4gICAgY29uc3QgcmVzb3VyY2VOYW1lID0gdGhpcy5nZXRSZXNvdXJjZU5hbWVBdHRyaWJ1dGUoam9iUmVzb3VyY2UucmVmKTtcbiAgICB0aGlzLmpvYkFybiA9IHRoaXMuYnVpbGRKb2JBcm4odGhpcywgcmVzb3VyY2VOYW1lKTtcbiAgICB0aGlzLmpvYk5hbWUgPSByZXNvdXJjZU5hbWU7XG4gIH1cblxuICAvKipcbiAgICogU2V0IHRoZSBleGVjdXRhYmxlIGFyZ3VtZW50cyB3aXRoIGJlc3QgcHJhY3RpY2VzIGVuYWJsZWQgYnkgZGVmYXVsdFxuICAgKlxuICAgKiBAcGFyYW0gcHJvcHNcbiAgICogQHJldHVybnMgQW4gYXJyYXkgb2YgYXJndW1lbnRzIGZvciBHbHVlIHRvIHVzZSBvbiBleGVjdXRpb25cbiAgICovXG4gIHByaXZhdGUgZXhlY3V0YWJsZUFyZ3VtZW50cyhwcm9wczogUHlTcGFya1N0cmVhbWluZ0pvYlByb3BzKSB7XG4gICAgY29uc3QgYXJnczogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSA9IHt9O1xuICAgIGFyZ3NbJy0tam9iLWxhbmd1YWdlJ10gPSBKb2JMYW5ndWFnZS5QWVRIT047XG5cbiAgICBpZiAocHJvcHMuZXh0cmFQeXRob25GaWxlcyAmJiBwcm9wcy5leHRyYVB5dGhvbkZpbGVzLmxlbmd0aCA+IDApIHtcbiAgICAgIGFyZ3NbJy0tZXh0cmEtcHktZmlsZXMnXSA9IHByb3BzLmV4dHJhUHl0aG9uRmlsZXMubWFwKGNvZGUgPT4gdGhpcy5jb2RlUzNPYmplY3RVcmwoY29kZSkpLmpvaW4oJywnKTtcbiAgICB9XG4gICAgaWYgKHByb3BzLmV4dHJhRmlsZXMgJiYgcHJvcHMuZXh0cmFGaWxlcy5sZW5ndGggPiAwKSB7XG4gICAgICBhcmdzWyctLWV4dHJhLWZpbGVzJ10gPSBwcm9wcy5leHRyYUZpbGVzLm1hcChjb2RlID0+IHRoaXMuY29kZVMzT2JqZWN0VXJsKGNvZGUpKS5qb2luKCcsJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFyZ3M7XG4gIH1cblxuICBwcml2YXRlIHNldHVwU3BhcmtVSShyb2xlOiBpYW0uSVJvbGUsIHNwYXJrVWlQcm9wczogU3BhcmtVSVByb3BzKSB7XG4gICAgdmFsaWRhdGVTcGFya1VpUHJlZml4KHNwYXJrVWlQcm9wcy5wcmVmaXgpO1xuICAgIGNvbnN0IGJ1Y2tldCA9IHNwYXJrVWlQcm9wcy5idWNrZXQgPz8gbmV3IEJ1Y2tldCh0aGlzLCAnU3BhcmtVSUJ1Y2tldCcsIHsgZW5mb3JjZVNTTDogdHJ1ZSwgZW5jcnlwdGlvbjogQnVja2V0RW5jcnlwdGlvbi5TM19NQU5BR0VEIH0pO1xuICAgIGJ1Y2tldC5ncmFudFJlYWRXcml0ZShyb2xlLCBjbGVhblNwYXJrVWlQcmVmaXhGb3JHcmFudChzcGFya1VpUHJvcHMucHJlZml4KSk7XG4gICAgY29uc3QgYXJncyA9IHtcbiAgICAgICctLWVuYWJsZS1zcGFyay11aSc6ICd0cnVlJyxcbiAgICAgICctLXNwYXJrLWV2ZW50LWxvZ3MtcGF0aCc6IGJ1Y2tldC5zM1VybEZvck9iamVjdChzcGFya1VpUHJvcHMucHJlZml4KS5yZXBsYWNlKC9cXC8/JC8sICcvJyksIC8vIHBhdGggd2lsbCBhbHdheXMgZW5kIHdpdGggYSBzbGFzaFxuICAgIH07XG5cbiAgICByZXR1cm4ge1xuICAgICAgbG9jYXRpb246IHtcbiAgICAgICAgcHJlZml4OiBzcGFya1VpUHJvcHMucHJlZml4LFxuICAgICAgICBidWNrZXQsXG4gICAgICB9LFxuICAgICAgYXJncyxcbiAgICB9O1xuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import * as iam from 'aws-cdk-lib/aws-iam';
|
|
2
|
+
import { Job, JobProperties } from './job';
|
|
3
|
+
import { Construct } from 'constructs';
|
|
4
|
+
import { PythonVersion, MaxCapacity } from '../constants';
|
|
5
|
+
/**
|
|
6
|
+
* Properties for creating a Python Shell job
|
|
7
|
+
*/
|
|
8
|
+
export interface PythonShellJobProps extends JobProperties {
|
|
9
|
+
/**
|
|
10
|
+
* Python Version
|
|
11
|
+
* The version of Python to use to execute this job
|
|
12
|
+
* @default 3.9 for Shell Jobs
|
|
13
|
+
**/
|
|
14
|
+
readonly pythonVersion?: PythonVersion;
|
|
15
|
+
/**
|
|
16
|
+
* The total number of DPU to assign to the Python Job
|
|
17
|
+
*
|
|
18
|
+
* @default 0.0625
|
|
19
|
+
*/
|
|
20
|
+
readonly maxCapacity?: MaxCapacity;
|
|
21
|
+
/**
|
|
22
|
+
* Specifies whether job run queuing is enabled for the job runs for this job.
|
|
23
|
+
* A value of true means job run queuing is enabled for the job runs.
|
|
24
|
+
* If false or not populated, the job runs will not be considered for queueing.
|
|
25
|
+
* If this field does not match the value set in the job run, then the value from
|
|
26
|
+
* the job run field will be used. This property must be set to false for flex jobs.
|
|
27
|
+
* If this property is enabled, maxRetries must be set to zero.
|
|
28
|
+
*
|
|
29
|
+
* @default false
|
|
30
|
+
*/
|
|
31
|
+
readonly jobRunQueuingEnabled?: boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Python Shell Jobs class
|
|
35
|
+
*
|
|
36
|
+
* A Python shell job runs Python scripts as a shell and supports a Python version that
|
|
37
|
+
* depends on the AWS Glue version you are using.
|
|
38
|
+
* This can be used to schedule and run tasks that don't require an Apache Spark environment.
|
|
39
|
+
*/
|
|
40
|
+
export declare class PythonShellJob extends Job {
|
|
41
|
+
readonly jobArn: string;
|
|
42
|
+
readonly jobName: string;
|
|
43
|
+
readonly role: iam.IRole;
|
|
44
|
+
readonly grantPrincipal: iam.IPrincipal;
|
|
45
|
+
/**
|
|
46
|
+
* PythonShellJob constructor
|
|
47
|
+
*/
|
|
48
|
+
constructor(scope: Construct, id: string, props: PythonShellJobProps);
|
|
49
|
+
/**
|
|
50
|
+
* Set the executable arguments with best practices enabled by default
|
|
51
|
+
*
|
|
52
|
+
* @returns An array of arguments for Glue to use on execution
|
|
53
|
+
*/
|
|
54
|
+
private executableArguments;
|
|
55
|
+
}
|