@odigos/aws-cdk 0.0.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/lib/index.js ADDED
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.SAR_SEMANTIC_VERSION = exports.SAR_APPLICATIONS = exports.LAYER_ARNS = exports.ODIGOS_VERSION = exports.ENV_LOGS_EXPORTER = exports.ENV_METRICS_EXPORTER = exports.ENV_TRACES_EXPORTER = exports.ENV_COLLECTOR_CONFIG_URI = exports.renderCollectorConfig = exports.layerNameFor = exports.execWrapperFor = exports.languageFromRuntime = exports.odigosLayerName = void 0;
18
+ __exportStar(require("./types"), exports);
19
+ __exportStar(require("./instrumentation"), exports);
20
+ var layer_resolver_1 = require("./layer-resolver");
21
+ Object.defineProperty(exports, "odigosLayerName", { enumerable: true, get: function () { return layer_resolver_1.odigosLayerName; } });
22
+ var runtime_1 = require("./runtime");
23
+ Object.defineProperty(exports, "languageFromRuntime", { enumerable: true, get: function () { return runtime_1.languageFromRuntime; } });
24
+ Object.defineProperty(exports, "execWrapperFor", { enumerable: true, get: function () { return runtime_1.execWrapperFor; } });
25
+ Object.defineProperty(exports, "layerNameFor", { enumerable: true, get: function () { return runtime_1.layerNameFor; } });
26
+ var collector_config_1 = require("./collector-config");
27
+ Object.defineProperty(exports, "renderCollectorConfig", { enumerable: true, get: function () { return collector_config_1.renderCollectorConfig; } });
28
+ Object.defineProperty(exports, "ENV_COLLECTOR_CONFIG_URI", { enumerable: true, get: function () { return collector_config_1.ENV_COLLECTOR_CONFIG_URI; } });
29
+ Object.defineProperty(exports, "ENV_TRACES_EXPORTER", { enumerable: true, get: function () { return collector_config_1.ENV_TRACES_EXPORTER; } });
30
+ Object.defineProperty(exports, "ENV_METRICS_EXPORTER", { enumerable: true, get: function () { return collector_config_1.ENV_METRICS_EXPORTER; } });
31
+ Object.defineProperty(exports, "ENV_LOGS_EXPORTER", { enumerable: true, get: function () { return collector_config_1.ENV_LOGS_EXPORTER; } });
32
+ var layers_1 = require("./generated/layers");
33
+ Object.defineProperty(exports, "ODIGOS_VERSION", { enumerable: true, get: function () { return layers_1.ODIGOS_VERSION; } });
34
+ Object.defineProperty(exports, "LAYER_ARNS", { enumerable: true, get: function () { return layers_1.LAYER_ARNS; } });
35
+ Object.defineProperty(exports, "SAR_APPLICATIONS", { enumerable: true, get: function () { return layers_1.SAR_APPLICATIONS; } });
36
+ Object.defineProperty(exports, "SAR_SEMANTIC_VERSION", { enumerable: true, get: function () { return layers_1.SAR_SEMANTIC_VERSION; } });
37
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwwQ0FBd0I7QUFDeEIsb0RBQWtDO0FBQ2xDLG1EQUFtRDtBQUExQyxpSEFBQSxlQUFlLE9BQUE7QUFDeEIscUNBQThFO0FBQXJFLDhHQUFBLG1CQUFtQixPQUFBO0FBQUUseUdBQUEsY0FBYyxPQUFBO0FBQUUsdUdBQUEsWUFBWSxPQUFBO0FBQzFELHVEQU00QjtBQUwxQix5SEFBQSxxQkFBcUIsT0FBQTtBQUNyQiw0SEFBQSx3QkFBd0IsT0FBQTtBQUN4Qix1SEFBQSxtQkFBbUIsT0FBQTtBQUNuQix3SEFBQSxvQkFBb0IsT0FBQTtBQUNwQixxSEFBQSxpQkFBaUIsT0FBQTtBQUVuQiw2Q0FBd0c7QUFBL0Ysd0dBQUEsY0FBYyxPQUFBO0FBQUUsb0dBQUEsVUFBVSxPQUFBO0FBQUUsMEdBQUEsZ0JBQWdCLE9BQUE7QUFBRSw4R0FBQSxvQkFBb0IsT0FBQSIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vdHlwZXMnO1xuZXhwb3J0ICogZnJvbSAnLi9pbnN0cnVtZW50YXRpb24nO1xuZXhwb3J0IHsgb2RpZ29zTGF5ZXJOYW1lIH0gZnJvbSAnLi9sYXllci1yZXNvbHZlcic7XG5leHBvcnQgeyBsYW5ndWFnZUZyb21SdW50aW1lLCBleGVjV3JhcHBlckZvciwgbGF5ZXJOYW1lRm9yIH0gZnJvbSAnLi9ydW50aW1lJztcbmV4cG9ydCB7XG4gIHJlbmRlckNvbGxlY3RvckNvbmZpZyxcbiAgRU5WX0NPTExFQ1RPUl9DT05GSUdfVVJJLFxuICBFTlZfVFJBQ0VTX0VYUE9SVEVSLFxuICBFTlZfTUVUUklDU19FWFBPUlRFUixcbiAgRU5WX0xPR1NfRVhQT1JURVIsXG59IGZyb20gJy4vY29sbGVjdG9yLWNvbmZpZyc7XG5leHBvcnQgeyBPRElHT1NfVkVSU0lPTiwgTEFZRVJfQVJOUywgU0FSX0FQUExJQ0FUSU9OUywgU0FSX1NFTUFOVElDX1ZFUlNJT04gfSBmcm9tICcuL2dlbmVyYXRlZC9sYXllcnMnO1xuIl19
@@ -0,0 +1,186 @@
1
+ import { IAspect } from 'aws-cdk-lib';
2
+ import * as lambda from 'aws-cdk-lib/aws-lambda';
3
+ import { Construct, IConstruct } from 'constructs';
4
+ import { OdigosDestination, OdigosInstrumentationMode, OdigosJavaHandlerDistro, OdigosLayerSource } from './types';
5
+ /**
6
+ * Options shared by the construct and the aspect.
7
+ */
8
+ export interface OdigosInstrumentationOptions {
9
+ /**
10
+ * Where the in-Lambda collector exports to.
11
+ */
12
+ readonly destination: OdigosDestination;
13
+ /**
14
+ * Where the Odigos layer comes from.
15
+ *
16
+ * @default OdigosLayerSource.ODIGOS_PUBLIC
17
+ */
18
+ readonly layerSource?: OdigosLayerSource;
19
+ /**
20
+ * Handler mode or web-server (Lambda Web Adapter) mode.
21
+ *
22
+ * There is no auto-detection, and that is deliberate rather than an omission: detecting the web adapter
23
+ * means inspecting the function's other layers, which at synth time are frequently unresolved tokens.
24
+ * A detector that is right most of the time would silently break the functions it got wrong.
25
+ *
26
+ * @default OdigosInstrumentationMode.HANDLER
27
+ */
28
+ readonly mode?: OdigosInstrumentationMode;
29
+ /**
30
+ * Which of the Java layer's four wrapper scripts to use. Ignored for other languages.
31
+ *
32
+ * @default OdigosJavaHandlerDistro.OTEL_HANDLER
33
+ */
34
+ readonly javaHandlerDistro?: OdigosJavaHandlerDistro;
35
+ /**
36
+ * `OTEL_SERVICE_NAME` for every function this instruments.
37
+ *
38
+ * Usually wrong to set when instrumenting more than one function — they would all report as the same
39
+ * service.
40
+ *
41
+ * Left unset, a function reports as its explicitly-set physical name if it has one, and otherwise as
42
+ * its construct id. It deliberately does not default to the generated physical name: that value is a
43
+ * `Ref` to the function itself, and a function referencing itself in its own environment is a
44
+ * CloudFormation dependency cycle.
45
+ *
46
+ * @default - the function's physical name if explicitly set, otherwise its construct id
47
+ */
48
+ readonly serviceName?: string;
49
+ /**
50
+ * Raise in-function OpenTelemetry verbosity (`OTEL_LOG_LEVEL=debug`).
51
+ *
52
+ * The layer, SDK and collector then emit span and OTLP-export diagnostics into the function's CloudWatch
53
+ * log group. Useful while wiring up a destination, expensive to leave on.
54
+ *
55
+ * Has no effect in web-server mode, matching the connector, which never sets a log level there.
56
+ *
57
+ * @default false
58
+ */
59
+ readonly debug?: boolean;
60
+ /**
61
+ * Attach this layer instead of resolving one. Overrides `layerSource` entirely.
62
+ *
63
+ * The escape hatch for a layer mirrored into a private registry or an internal account. The layer must
64
+ * have the same contents as the Odigos one — the environment set here assumes its exact script layout.
65
+ *
66
+ * @default - resolved from layerSource
67
+ */
68
+ readonly layerVersion?: lambda.ILayerVersion;
69
+ /**
70
+ * The value the function already needs in its language loader variable (`NODE_OPTIONS`,
71
+ * `JAVA_TOOL_OPTIONS` or `PYTHONPATH`), which the Odigos loader is joined to rather than replacing.
72
+ *
73
+ * Only used in web-server mode. It has to be passed explicitly because CDK's `lambda.Function` exposes
74
+ * no way to read back an environment variable set elsewhere in the app — an omitted value here is
75
+ * silently overwritten, which for `NODE_OPTIONS` can mean losing a flag the app needs to boot.
76
+ *
77
+ * @default - the loader variable is set to the Odigos value alone
78
+ */
79
+ readonly existingLoaderValue?: string;
80
+ /**
81
+ * Skip functions whose runtime has no OpenTelemetry Lambda layer instead of throwing.
82
+ *
83
+ * `dotnet*` and `provided.*` (Go, custom runtimes) have no language layer upstream. Explicitly
84
+ * instrumenting one is a mistake worth failing on; sweeping a whole stack with the aspect and hitting
85
+ * one is not, which is why the aspect defaults this to `true` and the construct to `false`.
86
+ *
87
+ * @default false
88
+ */
89
+ readonly skipUnsupportedRuntimes?: boolean;
90
+ }
91
+ /**
92
+ * Props for {@link OdigosLambdaInstrumentation}.
93
+ */
94
+ export interface OdigosLambdaInstrumentationProps extends OdigosInstrumentationOptions {
95
+ /**
96
+ * Functions to instrument on construction. More can be added with `instrument()`.
97
+ *
98
+ * @default - none
99
+ */
100
+ readonly functions?: lambda.Function[];
101
+ }
102
+ /**
103
+ * Instruments AWS Lambda functions with the Odigos OpenTelemetry layer.
104
+ *
105
+ * ```ts
106
+ * const odigos = new OdigosLambdaInstrumentation(this, 'Odigos', {
107
+ * destination: { endpoint: 'otlp.example.com:4317' },
108
+ * functions: [apiFn, workerFn],
109
+ * });
110
+ * odigos.instrument(anotherFn);
111
+ * ```
112
+ *
113
+ * What it does to each function: attaches the layer for the function's language and architecture, sets
114
+ * `AWS_LAMBDA_EXEC_WRAPPER` so the layer loads the SDK, sets `OTEL_SERVICE_NAME`, and hands the in-Lambda
115
+ * collector its entire configuration inline through `OPENTELEMETRY_COLLECTOR_CONFIG_URI`.
116
+ *
117
+ * The function's SDK exports to the collector on localhost, not to your destination. The collector
118
+ * forwards after the handler has already returned, so a slow destination costs billed duration rather
119
+ * than caller latency.
120
+ *
121
+ * ## Do not also instrument these functions with the connector
122
+ *
123
+ * The Odigos AWS connector instruments live functions by mutating them, and reconciles them back to its
124
+ * own desired state on every pass. A function instrumented here and also enabled as a connector source
125
+ * ends up owned by both: each `cdk deploy` reasserts the CDK's environment, each reconcile reasserts the
126
+ * connector's, and every round trip publishes a new function version.
127
+ *
128
+ * Choose one per function. This construct never sets the connector's `ODIGOS_MANAGED` ownership marker,
129
+ * so an IaC-instrumented function is not one the connector will roll back — but it will happily take it
130
+ * over if you enable it as a source.
131
+ */
132
+ export declare class OdigosLambdaInstrumentation extends Construct {
133
+ private readonly options;
134
+ private readonly resolver;
135
+ private readonly collectorConfig;
136
+ private readonly instrumented;
137
+ constructor(scope: Construct, id: string, props: OdigosLambdaInstrumentationProps);
138
+ /**
139
+ * Instruments one function. Idempotent — instrumenting the same function twice is a no-op rather than a
140
+ * doubled loader value.
141
+ */
142
+ instrument(fn: lambda.Function): void;
143
+ /** Instruments every function in the list. */
144
+ instrumentAll(functions: lambda.Function[]): void;
145
+ /**
146
+ * The environment applied to one function.
147
+ *
148
+ * Mirrors `applyHandlerEnv` / `applyWebServerEnv` in the connector, including what is deliberately NOT
149
+ * set: `OTEL_EXPORTER_OTLP_ENDPOINT` stays unset so the SDK keeps exporting to the in-Lambda collector
150
+ * on localhost rather than blocking the invocation on the remote destination, and an enabled signal's
151
+ * `OTEL_*_EXPORTER` stays unset because `otlp` is already the SDK default.
152
+ */
153
+ private environmentFor;
154
+ }
155
+ /**
156
+ * Props for {@link OdigosInstrumentationAspect}.
157
+ */
158
+ export interface OdigosInstrumentationAspectProps extends OdigosInstrumentationOptions {
159
+ }
160
+ /**
161
+ * Applies Odigos instrumentation to every `lambda.Function` in a scope.
162
+ *
163
+ * ```ts
164
+ * Aspects.of(stack).add(new OdigosInstrumentationAspect(stack, {
165
+ * destination: { endpoint: 'otlp.example.com:4317' },
166
+ * }));
167
+ * ```
168
+ *
169
+ * `skipUnsupportedRuntimes` defaults to `true` here, unlike the construct: an aspect visits every function
170
+ * in the scope, including ones whose runtime has no OpenTelemetry layer, and failing the whole synth
171
+ * because a stack happens to contain one Go function is not useful. Each skip is reported as a synth
172
+ * warning, so it is visible rather than silent.
173
+ *
174
+ * The aspect instruments what exists in the tree when it runs. A function added by a later aspect is not
175
+ * visited; use the construct directly for those.
176
+ */
177
+ export declare class OdigosInstrumentationAspect implements IAspect {
178
+ private readonly instrumentation;
179
+ /**
180
+ * @param scope where the shared layer constructs are created. Usually the same scope the aspect is
181
+ * applied to. It is a separate argument from the visited nodes because the layer (and, in `IN_ACCOUNT`
182
+ * mode, the nested SAR application) is created once and shared by every function the aspect visits.
183
+ */
184
+ constructor(scope: Construct, props: OdigosInstrumentationAspectProps);
185
+ visit(node: IConstruct): void;
186
+ }
@@ -0,0 +1,212 @@
1
+ "use strict";
2
+ var _a, _b;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.OdigosInstrumentationAspect = exports.OdigosLambdaInstrumentation = void 0;
5
+ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
6
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
7
+ const lambda = require("aws-cdk-lib/aws-lambda");
8
+ const constructs_1 = require("constructs");
9
+ const collector_config_1 = require("./collector-config");
10
+ const layers_1 = require("./generated/layers");
11
+ const layer_resolver_1 = require("./layer-resolver");
12
+ const runtime_1 = require("./runtime");
13
+ const types_1 = require("./types");
14
+ /** `AWS_LAMBDA_EXEC_WRAPPER` — the layer's entry point in handler mode. */
15
+ const ENV_EXEC_WRAPPER = 'AWS_LAMBDA_EXEC_WRAPPER';
16
+ /** Service name reported on every span, metric and log record. */
17
+ const ENV_SERVICE_NAME = 'OTEL_SERVICE_NAME';
18
+ /** Raises in-function OpenTelemetry verbosity into the function's CloudWatch log group. */
19
+ const ENV_OTEL_LOG_LEVEL = 'OTEL_LOG_LEVEL';
20
+ /**
21
+ * Marker recording that this function was instrumented by IaC, and by which version.
22
+ *
23
+ * Deliberately NOT `ODIGOS_MANAGED`. That variable is the connector's OWNERSHIP PROOF: a function
24
+ * carrying it is one the connector believes it instrumented, whose environment it will converge on every
25
+ * reconcile and strip on rollback — using a snapshot of "the customer's original values" that a CDK
26
+ * deployment never wrote. Setting it here would hand the connector a function it does not own, with a
27
+ * snapshot describing a state that never existed.
28
+ *
29
+ * This variable is informational only. Nothing reads it.
30
+ */
31
+ const ENV_IAC_MARKER = 'ODIGOS_IAC';
32
+ /**
33
+ * The service a function reports as, when the caller has not named one.
34
+ *
35
+ * NOT `fn.functionName`. For a function whose physical name CloudFormation generates, that property is a
36
+ * `Ref` to the function itself — putting it in the function's own environment makes the resource depend
37
+ * on its own creation, and CloudFormation rejects the template with a dependency cycle. Every
38
+ * instrumented function would fail to deploy, at deploy time rather than synth time.
39
+ *
40
+ * So: use the physical name when the caller set one explicitly (`resolve` yields a literal string for a
41
+ * known physical name, and a `Ref` object otherwise), and otherwise fall back to the construct id, which
42
+ * is what the function is called in the code and needs no reference at all.
43
+ *
44
+ * The connector reports the real AWS function name for the functions IT instruments. A function with a
45
+ * generated physical name therefore reports differently under the two paths — pass `serviceName`
46
+ * explicitly if that matters.
47
+ */
48
+ function defaultServiceName(fn) {
49
+ const resolved = aws_cdk_lib_1.Stack.of(fn).resolve(fn.functionName);
50
+ return typeof resolved === 'string' ? resolved : fn.node.id;
51
+ }
52
+ /**
53
+ * Instruments AWS Lambda functions with the Odigos OpenTelemetry layer.
54
+ *
55
+ * ```ts
56
+ * const odigos = new OdigosLambdaInstrumentation(this, 'Odigos', {
57
+ * destination: { endpoint: 'otlp.example.com:4317' },
58
+ * functions: [apiFn, workerFn],
59
+ * });
60
+ * odigos.instrument(anotherFn);
61
+ * ```
62
+ *
63
+ * What it does to each function: attaches the layer for the function's language and architecture, sets
64
+ * `AWS_LAMBDA_EXEC_WRAPPER` so the layer loads the SDK, sets `OTEL_SERVICE_NAME`, and hands the in-Lambda
65
+ * collector its entire configuration inline through `OPENTELEMETRY_COLLECTOR_CONFIG_URI`.
66
+ *
67
+ * The function's SDK exports to the collector on localhost, not to your destination. The collector
68
+ * forwards after the handler has already returned, so a slow destination costs billed duration rather
69
+ * than caller latency.
70
+ *
71
+ * ## Do not also instrument these functions with the connector
72
+ *
73
+ * The Odigos AWS connector instruments live functions by mutating them, and reconciles them back to its
74
+ * own desired state on every pass. A function instrumented here and also enabled as a connector source
75
+ * ends up owned by both: each `cdk deploy` reasserts the CDK's environment, each reconcile reasserts the
76
+ * connector's, and every round trip publishes a new function version.
77
+ *
78
+ * Choose one per function. This construct never sets the connector's `ODIGOS_MANAGED` ownership marker,
79
+ * so an IaC-instrumented function is not one the connector will roll back — but it will happily take it
80
+ * over if you enable it as a source.
81
+ */
82
+ class OdigosLambdaInstrumentation extends constructs_1.Construct {
83
+ constructor(scope, id, props) {
84
+ super(scope, id);
85
+ this.instrumented = new Set();
86
+ this.options = props;
87
+ this.resolver = new layer_resolver_1.OdigosLayerResolver(this, props.layerSource ?? types_1.OdigosLayerSource.ODIGOS_PUBLIC);
88
+ // Rendered once. It depends only on the destination, and rendering it per function would make an
89
+ // accidental difference between two functions possible.
90
+ this.collectorConfig = (0, collector_config_1.renderCollectorConfig)(props.destination);
91
+ for (const fn of props.functions ?? []) {
92
+ this.instrument(fn);
93
+ }
94
+ }
95
+ /**
96
+ * Instruments one function. Idempotent — instrumenting the same function twice is a no-op rather than a
97
+ * doubled loader value.
98
+ */
99
+ instrument(fn) {
100
+ const key = fn.node.path;
101
+ if (this.instrumented.has(key)) {
102
+ return;
103
+ }
104
+ const runtimeName = fn.runtime.name;
105
+ const language = (0, runtime_1.languageFromRuntime)(runtimeName);
106
+ if (!language) {
107
+ const message = `Odigos: runtime "${runtimeName}" has no OpenTelemetry Lambda layer ` +
108
+ '(upstream publishes layers for python, nodejs, java and ruby only), so this function cannot be instrumented.';
109
+ if (this.options.skipUnsupportedRuntimes) {
110
+ aws_cdk_lib_1.Annotations.of(fn).addWarningV2('@odigos/aws-cdk:unsupportedRuntime', `${message} Skipping.`);
111
+ return;
112
+ }
113
+ throw new Error(`${message} Set skipUnsupportedRuntimes: true to skip it instead.`);
114
+ }
115
+ this.instrumented.add(key);
116
+ const architecture = fn.architecture.name;
117
+ const layer = this.options.layerVersion ?? this.resolver.resolve(language, architecture);
118
+ fn.addLayers(layer);
119
+ for (const [name, value] of Object.entries(this.environmentFor(fn, language))) {
120
+ fn.addEnvironment(name, value);
121
+ }
122
+ }
123
+ /** Instruments every function in the list. */
124
+ instrumentAll(functions) {
125
+ for (const fn of functions) {
126
+ this.instrument(fn);
127
+ }
128
+ }
129
+ /**
130
+ * The environment applied to one function.
131
+ *
132
+ * Mirrors `applyHandlerEnv` / `applyWebServerEnv` in the connector, including what is deliberately NOT
133
+ * set: `OTEL_EXPORTER_OTLP_ENDPOINT` stays unset so the SDK keeps exporting to the in-Lambda collector
134
+ * on localhost rather than blocking the invocation on the remote destination, and an enabled signal's
135
+ * `OTEL_*_EXPORTER` stays unset because `otlp` is already the SDK default.
136
+ */
137
+ environmentFor(fn, language) {
138
+ const { destination, mode, debug, serviceName, javaHandlerDistro, existingLoaderValue } = this.options;
139
+ const webServer = mode === types_1.OdigosInstrumentationMode.WEB_SERVER;
140
+ const env = {
141
+ [ENV_SERVICE_NAME]: serviceName ?? defaultServiceName(fn),
142
+ [collector_config_1.ENV_COLLECTOR_CONFIG_URI]: this.collectorConfig,
143
+ [ENV_IAC_MARKER]: JSON.stringify({ v: 1, source: 'cdk', version: layers_1.ODIGOS_VERSION || 'unreleased' }),
144
+ };
145
+ if (webServer) {
146
+ // No exec wrapper: the Lambda Web Adapter owns it, and overwriting it stops the function serving.
147
+ Object.assign(env, (0, runtime_1.webServerEnv)(language, existingLoaderValue));
148
+ }
149
+ else {
150
+ env[ENV_EXEC_WRAPPER] = (0, runtime_1.execWrapperFor)(language, javaHandlerDistro);
151
+ if (debug) {
152
+ env[ENV_OTEL_LOG_LEVEL] = 'debug';
153
+ }
154
+ }
155
+ // Suppress the signals the destination does not accept. A signal with no collector pipeline is refused
156
+ // at the receiver on every batch, so telling the SDK not to produce it is the half that stops the
157
+ // error loop; the pipeline being absent is the half that stops the export.
158
+ const overrides = [
159
+ [collector_config_1.ENV_TRACES_EXPORTER, (0, collector_config_1.exporterOverrideFor)((0, collector_config_1.signalEnabled)(destination.traces))],
160
+ [collector_config_1.ENV_METRICS_EXPORTER, (0, collector_config_1.exporterOverrideFor)((0, collector_config_1.signalEnabled)(destination.metrics))],
161
+ [collector_config_1.ENV_LOGS_EXPORTER, (0, collector_config_1.exporterOverrideFor)((0, collector_config_1.signalEnabled)(destination.logs))],
162
+ ];
163
+ for (const [name, value] of overrides) {
164
+ if (value !== undefined) {
165
+ env[name] = value;
166
+ }
167
+ }
168
+ return env;
169
+ }
170
+ }
171
+ exports.OdigosLambdaInstrumentation = OdigosLambdaInstrumentation;
172
+ _a = JSII_RTTI_SYMBOL_1;
173
+ OdigosLambdaInstrumentation[_a] = { fqn: "@odigos/aws-cdk.OdigosLambdaInstrumentation", version: "0.0.0" };
174
+ /**
175
+ * Applies Odigos instrumentation to every `lambda.Function` in a scope.
176
+ *
177
+ * ```ts
178
+ * Aspects.of(stack).add(new OdigosInstrumentationAspect(stack, {
179
+ * destination: { endpoint: 'otlp.example.com:4317' },
180
+ * }));
181
+ * ```
182
+ *
183
+ * `skipUnsupportedRuntimes` defaults to `true` here, unlike the construct: an aspect visits every function
184
+ * in the scope, including ones whose runtime has no OpenTelemetry layer, and failing the whole synth
185
+ * because a stack happens to contain one Go function is not useful. Each skip is reported as a synth
186
+ * warning, so it is visible rather than silent.
187
+ *
188
+ * The aspect instruments what exists in the tree when it runs. A function added by a later aspect is not
189
+ * visited; use the construct directly for those.
190
+ */
191
+ class OdigosInstrumentationAspect {
192
+ /**
193
+ * @param scope where the shared layer constructs are created. Usually the same scope the aspect is
194
+ * applied to. It is a separate argument from the visited nodes because the layer (and, in `IN_ACCOUNT`
195
+ * mode, the nested SAR application) is created once and shared by every function the aspect visits.
196
+ */
197
+ constructor(scope, props) {
198
+ this.instrumentation = new OdigosLambdaInstrumentation(scope, 'OdigosInstrumentationAspect', {
199
+ skipUnsupportedRuntimes: true,
200
+ ...props,
201
+ });
202
+ }
203
+ visit(node) {
204
+ if (node instanceof lambda.Function) {
205
+ this.instrumentation.instrument(node);
206
+ }
207
+ }
208
+ }
209
+ exports.OdigosInstrumentationAspect = OdigosInstrumentationAspect;
210
+ _b = JSII_RTTI_SYMBOL_1;
211
+ OdigosInstrumentationAspect[_b] = { fqn: "@odigos/aws-cdk.OdigosInstrumentationAspect", version: "0.0.0" };
212
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5zdHJ1bWVudGF0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2luc3RydW1lbnRhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLDZDQUEwRDtBQUMxRCxpREFBaUQ7QUFDakQsMkNBQW1EO0FBQ25ELHlEQVE0QjtBQUM1QiwrQ0FBb0Q7QUFDcEQscURBQXVEO0FBQ3ZELHVDQUE4RTtBQUM5RSxtQ0FLaUI7QUFFakIsMkVBQTJFO0FBQzNFLE1BQU0sZ0JBQWdCLEdBQUcseUJBQXlCLENBQUM7QUFDbkQsa0VBQWtFO0FBQ2xFLE1BQU0sZ0JBQWdCLEdBQUcsbUJBQW1CLENBQUM7QUFDN0MsMkZBQTJGO0FBQzNGLE1BQU0sa0JBQWtCLEdBQUcsZ0JBQWdCLENBQUM7QUFFNUM7Ozs7Ozs7Ozs7R0FVRztBQUNILE1BQU0sY0FBYyxHQUFHLFlBQVksQ0FBQztBQUVwQzs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFDSCxTQUFTLGtCQUFrQixDQUFDLEVBQW1CO0lBQzdDLE1BQU0sUUFBUSxHQUFHLG1CQUFLLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDdkQsT0FBTyxPQUFPLFFBQVEsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7QUFDOUQsQ0FBQztBQTZHRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E2Qkc7QUFDSCxNQUFhLDJCQUE0QixTQUFRLHNCQUFTO0lBTXhELFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBdUM7UUFDL0UsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUhGLGlCQUFZLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztRQUtoRCxJQUFJLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztRQUNyQixJ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RyxLQUFLLENBQUM7WUFDcEIsQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPLEdBQUcsQ0FBQztJQUNiLENBQUM7O0FBekdILGtFQTBHQzs7O0FBT0Q7Ozs7Ozs7Ozs7Ozs7Ozs7R0FnQkc7QUFDSCxNQUFhLDJCQUEyQjtJQUd0Qzs7OztPQUlHO0lBQ0gsWUFBWSxLQUFnQixFQUFFLEtBQXVDO1FBQ25FLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSwyQkFBMkIsQ0FBQyxLQUFLLEVBQUUsNkJBQTZCLEVBQUU7WUFDM0YsdUJBQXVCLEVBQUUsSUFBSTtZQUM3QixHQUFHLEtBQUs7U0FDVCxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU0sS0FBSyxDQUFDLElBQWdCO1FBQzNCLElBQUksSUFBSSxZQUFZLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNwQyxJQUFJLENBQUMsZUFBZSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN4QyxDQUFDO0lBQ0gsQ0FBQzs7QUFuQkgsa0VBb0JDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQW5ub3RhdGlvbnMsIElBc3BlY3QsIFN0YWNrIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0ICogYXMgbGFtYmRhIGZyb20gJ2F3cy1jZGstbGliL2F3cy1sYW1iZGEnO1xuaW1wb3J0IHsgQ29uc3RydWN0LCBJQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQge1xuICBFTlZfQ09MTEVDVE9SX0NPTkZJR19VUkksXG4gIEVOVl9MT0dTX0VYUE9SVEVSLFxuICBFTlZfTUVUUklDU19FWFBPUlRFUixcbiAgRU5WX1RSQUNFU19FWFBPUlRFUixcbiAgZXhwb3J0ZXJPdmVycmlkZUZvcixcbiAgcmVuZGVyQ29sbGVjdG9yQ29uZmlnLFxuICBzaWduYWxFbmFibGVkLFxufSBmcm9tICcuL2NvbGxlY3Rvci1jb25maWcnO1xuaW1wb3J0IHsgT0RJR09TX1ZFUlNJT04gfSBmcm9tICcuL2dlbmVyYXRlZC9sYXllcnMnO1xuaW1wb3J0IHsgT2RpZ29zTGF5ZXJSZXNvbHZlciB9IGZyb20gJy4vbGF5ZXItcmVzb2x2ZXInO1xuaW1wb3J0IHsgZXhlY1dyYXBwZXJGb3IsIGxhbmd1YWdlRnJvbVJ1bnRpbWUsIHdlYlNlcnZlckVudiB9IGZyb20gJy4vcnVudGltZSc7XG5pbXBvcnQge1xuICBPZGlnb3NEZXN0aW5hdGlvbixcbiAgT2RpZ29zSW5zdHJ1bWVudGF0aW9uTW9kZSxcbiAgT2RpZ29zSmF2YUhhbmRsZXJEaXN0cm8sXG4gIE9kaWdvc0xheWVyU291cmNlLFxufSBmcm9tICcuL3R5cGVzJztcblxuLyoqIGBBV1NfTEFNQkRBX0VYRUNfV1JBUFBFUmAg4oCUIHRoZSBsYXllcidzIGVudHJ5IHBvaW50IGluIGhhbmRsZXIgbW9kZS4gKi9cbmNvbnN0IEVOVl9FWEVDX1dSQVBQRVIgPSAnQVdTX0xBTUJEQV9FWEVDX1dSQVBQRVInO1xuLyoqIFNlcnZpY2UgbmFtZSByZXBvcnRlZCBvbiBldmVyeSBzcGFuLCBtZXRyaWMgYW5kIGxvZyByZWNvcmQuICovXG5jb25zdCBFTlZfU0VSVklDRV9OQU1FID0gJ09URUxfU0VSVklDRV9OQU1FJztcbi8qKiBSYWlzZXMgaW4tZnVuY3Rpb24gT3BlblRlbGVtZXRyeSB2ZXJib3NpdHkgaW50byB0aGUgZnVuY3Rpb24ncyBDbG91ZFdhdGNoIGxvZyBncm91cC4gKi9cbmNvbnN0IEVOVl9PVEVMX0xPR19MRVZFTCA9ICdPVEVMX0xPR19MRVZFTCc7XG5cbi8qKlxuICogTWFya2VyIHJlY29yZGluZyB0aGF0IHRoaXMgZnVuY3Rpb24gd2FzIGluc3RydW1lbnRlZCBieSBJYUMsIGFuZCBieSB3aGljaCB2ZXJzaW9uLlxuICpcbiAqIERlbGliZXJhdGVseSBOT1QgYE9ESUdPU19NQU5BR0VEYC4gVGhhdCB2YXJpYWJsZSBpcyB0aGUgY29ubmVjdG9yJ3MgT1dORVJTSElQIFBST09GOiBhIGZ1bmN0aW9uXG4gKiBjYXJyeWluZyBpdCBpcyBvbmUgdGhlIGNvbm5lY3RvciBiZWxpZXZlcyBpdCBpbnN0cnVtZW50ZWQsIHdob3NlIGVudmlyb25tZW50IGl0IHdpbGwgY29udmVyZ2Ugb24gZXZlcnlcbiAqIHJlY29uY2lsZSBhbmQgc3RyaXAgb24gcm9sbGJhY2sg4oCUIHVzaW5nIGEgc25hcHNob3Qgb2YgXCJ0aGUgY3VzdG9tZXIncyBvcmlnaW5hbCB2YWx1ZXNcIiB0aGF0IGEgQ0RLXG4gKiBkZXBsb3ltZW50IG5ldmVyIHdyb3RlLiBTZXR0aW5nIGl0IGhlcmUgd291bGQgaGFuZCB0aGUgY29ubmVjdG9yIGEgZnVuY3Rpb24gaXQgZG9lcyBub3Qgb3duLCB3aXRoIGFcbiAqIHNuYXBzaG90IGRlc2NyaWJpbmcgYSBzdGF0ZSB0aGF0IG5ldmVyIGV4aXN0ZWQuXG4gKlxuICogVGhpcyB2YXJpYWJsZSBpcyBpbmZvcm1hdGlvbmFsIG9ubHkuIE5vdGhpbmcgcmVhZHMgaXQuXG4gKi9cbmNvbnN0IEVOVl9JQUNfTUFSS0VSID0gJ09ESUdPU19JQUMnO1xuXG4vKipcbiAqIFRoZSBzZXJ2aWNlIGEgZnVuY3Rpb24gcmVwb3J0cyBhcywgd2hlbiB0aGUgY2FsbGVyIGhhcyBub3QgbmFtZWQgb25lLlxuICpcbiAqIE5PVCBgZm4uZnVuY3Rpb25OYW1lYC4gRm9yIGEgZnVuY3Rpb24gd2hvc2UgcGh5c2ljYWwgbmFtZSBDbG91ZEZvcm1hdGlvbiBnZW5lcmF0ZXMsIHRoYXQgcHJvcGVydHkgaXMgYVxuICogYFJlZmAgdG8gdGhlIGZ1bmN0aW9uIGl0c2VsZiDigJQgcHV0dGluZyBpdCBpbiB0aGUgZnVuY3Rpb24ncyBvd24gZW52aXJvbm1lbnQgbWFrZXMgdGhlIHJlc291cmNlIGRlcGVuZFxuICogb24gaXRzIG93biBjcmVhdGlvbiwgYW5kIENsb3VkRm9ybWF0aW9uIHJlamVjdHMgdGhlIHRlbXBsYXRlIHdpdGggYSBkZXBlbmRlbmN5IGN5Y2xlLiBFdmVyeVxuICogaW5zdHJ1bWVudGVkIGZ1bmN0aW9uIHdvdWxkIGZhaWwgdG8gZGVwbG95LCBhdCBkZXBsb3kgdGltZSByYXRoZXIgdGhhbiBzeW50aCB0aW1lLlxuICpcbiAqIFNvOiB1c2UgdGhlIHBoeXNpY2FsIG5hbWUgd2hlbiB0aGUgY2FsbGVyIHNldCBvbmUgZXhwbGljaXRseSAoYHJlc29sdmVgIHlpZWxkcyBhIGxpdGVyYWwgc3RyaW5nIGZvciBhXG4gKiBrbm93biBwaHlzaWNhbCBuYW1lLCBhbmQgYSBgUmVmYCBvYmplY3Qgb3RoZXJ3aXNlKSwgYW5kIG90aGVyd2lzZSBmYWxsIGJhY2sgdG8gdGhlIGNvbnN0cnVjdCBpZCwgd2hpY2hcbiAqIGlzIHdoYXQgdGhlIGZ1bmN0aW9uIGlzIGNhbGxlZCBpbiB0aGUgY29kZSBhbmQgbmVlZHMgbm8gcmVmZXJlbmNlIGF0IGFsbC5cbiAqXG4gKiBUaGUgY29ubmVjdG9yIHJlcG9ydHMgdGhlIHJlYWwgQVdTIGZ1bmN0aW9uIG5hbWUgZm9yIHRoZSBmdW5jdGlvbnMgSVQgaW5zdHJ1bWVudHMuIEEgZnVuY3Rpb24gd2l0aCBhXG4gKiBnZW5lcmF0ZWQgcGh5c2ljYWwgbmFtZSB0aGVyZWZvcmUgcmVwb3J0cyBkaWZmZXJlbnRseSB1bmRlciB0aGUgdHdvIHBhdGhzIOKAlCBwYXNzIGBzZXJ2aWNlTmFtZWBcbiAqIGV4cGxpY2l0bHkgaWYgdGhhdCBtYXR0ZXJzLlxuICovXG5mdW5jdGlvbiBkZWZhdWx0U2VydmljZU5hbWUoZm46IGxhbWJkYS5GdW5jdGlvbik6IHN0cmluZyB7XG4gIGNvbnN0IHJlc29sdmVkID0gU3RhY2sub2YoZm4pLnJlc29sdmUoZm4uZnVuY3Rpb25OYW1lKTtcbiAgcmV0dXJuIHR5cGVvZiByZXNvbHZlZCA9PT0gJ3N0cmluZycgPyByZXNvbHZlZCA6IGZuLm5vZGUuaWQ7XG59XG5cbi8qKlxuICogT3B0aW9ucyBzaGFyZWQgYnkgdGhlIGNvbnN0cnVjdCBhbmQgdGhlIGFzcGVjdC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBPZGlnb3NJbnN0cnVtZW50YXRpb25PcHRpb25zIHtcbiAgLyoqXG4gICAqIFdoZXJlIHRoZSBpbi1MYW1iZGEgY29sbGVjdG9yIGV4cG9ydHMgdG8uXG4gICAqL1xuICByZWFkb25seSBkZXN0aW5hdGlvbjogT2RpZ29zRGVzdGluYXRpb247XG5cbiAgLyoqXG4gICAqIFdoZXJlIHRoZSBPZGlnb3MgbGF5ZXIgY29tZXMgZnJvbS5cbiAgICpcbiAgICogQGRlZmF1bHQgT2RpZ29zTGF5ZXJTb3VyY2UuT0RJR09TX1BVQkxJQ1xuICAgKi9cbiAgcmVhZG9ubHkgbGF5ZXJTb3VyY2U/OiBPZGlnb3NMYXllclNvdXJjZTtcblxuICAvKipcbiAgICogSGFuZGxlciBtb2RlIG9yIHdlYi1zZXJ2ZXIgKExhbWJkYSBXZWIgQWRhcHRlcikgbW9kZS5cbiAgICpcbiAgICogVGhlcmUgaXMgbm8gYXV0by1kZXRlY3Rpb24sIGFuZCB0aGF0IGlzIGRlbGliZXJhdGUgcmF0aGVyIHRoYW4gYW4gb21pc3Npb246IGRldGVjdGluZyB0aGUgd2ViIGFkYXB0ZXJcbiAgICogbWVhbnMgaW5zcGVjdGluZyB0aGUgZnVuY3Rpb24ncyBvdGhlciBsYXllcnMsIHdoaWNoIGF0IHN5bnRoIHRpbWUgYXJlIGZyZXF1ZW50bHkgdW5yZXNvbHZlZCB0b2tlbnMuXG4gICAqIEEgZGV0ZWN0b3IgdGhhdCBpcyByaWdodCBtb3N0IG9mIHRoZSB0aW1lIHdvdWxkIHNpbGVudGx5IGJyZWFrIHRoZSBmdW5jdGlvbnMgaXQgZ290IHdyb25nLlxuICAgKlxuICAgKiBAZGVmYXVsdCBPZGlnb3NJbnN0cnVtZW50YXRpb25Nb2RlLkhBTkRMRVJcbiAgICovXG4gIHJlYWRvbmx5IG1vZGU/OiBPZGlnb3NJbnN0cnVtZW50YXRpb25Nb2RlO1xuXG4gIC8qKlxuICAgKiBXaGljaCBvZiB0aGUgSmF2YSBsYXllcidzIGZvdXIgd3JhcHBlciBzY3JpcHRzIHRvIHVzZS4gSWdub3JlZCBmb3Igb3RoZXIgbGFuZ3VhZ2VzLlxuICAgKlxuICAgKiBAZGVmYXVsdCBPZGlnb3NKYXZhSGFuZGxlckRpc3Ryby5PVEVMX0hBTkRMRVJcbiAgICovXG4gIHJlYWRvbmx5IGphdmFIYW5kbGVyRGlzdHJvPzogT2RpZ29zSmF2YUhhbmRsZXJEaXN0cm87XG5cbiAgLyoqXG4gICAqIGBPVEVMX1NFUlZJQ0VfTkFNRWAgZm9yIGV2ZXJ5IGZ1bmN0aW9uIHRoaXMgaW5zdHJ1bWVudHMuXG4gICAqXG4gICAqIFVzdWFsbHkgd3JvbmcgdG8gc2V0IHdoZW4gaW5zdHJ1bWVudGluZyBtb3JlIHRoYW4gb25lIGZ1bmN0aW9uIOKAlCB0aGV5IHdvdWxkIGFsbCByZXBvcnQgYXMgdGhlIHNhbWVcbiAgICogc2VydmljZS5cbiAgICpcbiAgICogTGVmdCB1bnNldCwgYSBmdW5jdGlvbiByZXBvcnRzIGFzIGl0cyBleHBsaWNpdGx5LXNldCBwaHlzaWNhbCBuYW1lIGlmIGl0IGhhcyBvbmUsIGFuZCBvdGhlcndpc2UgYXNcbiAgICogaXRzIGNvbnN0cnVjdCBpZC4gSXQgZGVsaWJlcmF0ZWx5IGRvZXMgbm90IGRlZmF1bHQgdG8gdGhlIGdlbmVyYXRlZCBwaHlzaWNhbCBuYW1lOiB0aGF0IHZhbHVlIGlzIGFcbiAgICogYFJlZmAgdG8gdGhlIGZ1bmN0aW9uIGl0c2VsZiwgYW5kIGEgZnVuY3Rpb24gcmVmZXJlbmNpbmcgaXRzZWxmIGluIGl0cyBvd24gZW52aXJvbm1lbnQgaXMgYVxuICAgKiBDbG91ZEZvcm1hdGlvbiBkZXBlbmRlbmN5IGN5Y2xlLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIHRoZSBmdW5jdGlvbidzIHBoeXNpY2FsIG5hbWUgaWYgZXhwbGljaXRseSBzZXQsIG90aGVyd2lzZSBpdHMgY29uc3RydWN0IGlkXG4gICAqL1xuICByZWFkb25seSBzZXJ2aWNlTmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogUmFpc2UgaW4tZnVuY3Rpb24gT3BlblRlbGVtZXRyeSB2ZXJib3NpdHkgKGBPVEVMX0xPR19MRVZFTD1kZWJ1Z2ApLlxuICAgKlxuICAgKiBUaGUgbGF5ZXIsIFNESyBhbmQgY29sbGVjdG9yIHRoZW4gZW1pdCBzcGFuIGFuZCBPVExQLWV4cG9ydCBkaWFnbm9zdGljcyBpbnRvIHRoZSBmdW5jdGlvbidzIENsb3VkV2F0Y2hcbiAgICogbG9nIGdyb3VwLiBVc2VmdWwgd2hpbGUgd2lyaW5nIHVwIGEgZGVzdGluYXRpb24sIGV4cGVuc2l2ZSB0byBsZWF2ZSBvbi5cbiAgICpcbiAgICogSGFzIG5vIGVmZmVjdCBpbiB3ZWItc2VydmVyIG1vZGUsIG1hdGNoaW5nIHRoZSBjb25uZWN0b3IsIHdoaWNoIG5ldmVyIHNldHMgYSBsb2cgbGV2ZWwgdGhlcmUuXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBkZWJ1Zz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEF0dGFjaCB0aGlzIGxheWVyIGluc3RlYWQgb2YgcmVzb2x2aW5nIG9uZS4gT3ZlcnJpZGVzIGBsYXllclNvdXJjZWAgZW50aXJlbHkuXG4gICAqXG4gICAqIFRoZSBlc2NhcGUgaGF0Y2ggZm9yIGEgbGF5ZXIgbWlycm9yZWQgaW50byBhIHByaXZhdGUgcmVnaXN0cnkgb3IgYW4gaW50ZXJuYWwgYWNjb3VudC4gVGhlIGxheWVyIG11c3RcbiAgICogaGF2ZSB0aGUgc2FtZSBjb250ZW50cyBhcyB0aGUgT2RpZ29zIG9uZSDigJQgdGhlIGVudmlyb25tZW50IHNldCBoZXJlIGFzc3VtZXMgaXRzIGV4YWN0IHNjcmlwdCBsYXlvdXQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gcmVzb2x2ZWQgZnJvbSBsYXllclNvdXJjZVxuICAgKi9cbiAgcmVhZG9ubHkgbGF5ZXJWZXJzaW9uPzogbGFtYmRhLklMYXllclZlcnNpb247XG5cbiAgLyoqXG4gICAqIFRoZSB2YWx1ZSB0aGUgZnVuY3Rpb24gYWxyZWFkeSBuZWVkcyBpbiBpdHMgbGFuZ3VhZ2UgbG9hZGVyIHZhcmlhYmxlIChgTk9ERV9PUFRJT05TYCxcbiAgICogYEpBVkFfVE9PTF9PUFRJT05TYCBvciBgUFlUSE9OUEFUSGApLCB3aGljaCB0aGUgT2RpZ29zIGxvYWRlciBpcyBqb2luZWQgdG8gcmF0aGVyIHRoYW4gcmVwbGFjaW5nLlxuICAgKlxuICAgKiBPbmx5IHVzZWQgaW4gd2ViLXNlcnZlciBtb2RlLiBJdCBoYXMgdG8gYmUgcGFzc2VkIGV4cGxpY2l0bHkgYmVjYXVzZSBDREsncyBgbGFtYmRhLkZ1bmN0aW9uYCBleHBvc2VzXG4gICAqIG5vIHdheSB0byByZWFkIGJhY2sgYW4gZW52aXJvbm1lbnQgdmFyaWFibGUgc2V0IGVsc2V3aGVyZSBpbiB0aGUgYXBwIOKAlCBhbiBvbWl0dGVkIHZhbHVlIGhlcmUgaXNcbiAgICogc2lsZW50bHkgb3ZlcndyaXR0ZW4sIHdoaWNoIGZvciBgTk9ERV9PUFRJT05TYCBjYW4gbWVhbiBsb3NpbmcgYSBmbGFnIHRoZSBhcHAgbmVlZHMgdG8gYm9vdC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSB0aGUgbG9hZGVyIHZhcmlhYmxlIGlzIHNldCB0byB0aGUgT2RpZ29zIHZhbHVlIGFsb25lXG4gICAqL1xuICByZWFkb25seSBleGlzdGluZ0xvYWRlclZhbHVlPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBTa2lwIGZ1bmN0aW9ucyB3aG9zZSBydW50aW1lIGhhcyBubyBPcGVuVGVsZW1ldHJ5IExhbWJkYSBsYXllciBpbnN0ZWFkIG9mIHRocm93aW5nLlxuICAgKlxuICAgKiBgZG90bmV0KmAgYW5kIGBwcm92aWRlZC4qYCAoR28sIGN1c3RvbSBydW50aW1lcykgaGF2ZSBubyBsYW5ndWFnZSBsYXllciB1cHN0cmVhbS4gRXhwbGljaXRseVxuICAgKiBpbnN0cnVtZW50aW5nIG9uZSBpcyBhIG1pc3Rha2Ugd29ydGggZmFpbGluZyBvbjsgc3dlZXBpbmcgYSB3aG9sZSBzdGFjayB3aXRoIHRoZSBhc3BlY3QgYW5kIGhpdHRpbmdcbiAgICogb25lIGlzIG5vdCwgd2hpY2ggaXMgd2h5IHRoZSBhc3BlY3QgZGVmYXVsdHMgdGhpcyB0byBgdHJ1ZWAgYW5kIHRoZSBjb25zdHJ1Y3QgdG8gYGZhbHNlYC5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IHNraXBVbnN1cHBvcnRlZFJ1bnRpbWVzPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBQcm9wcyBmb3Ige0BsaW5rIE9kaWdvc0xhbWJkYUluc3RydW1lbnRhdGlvbn0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgT2RpZ29zTGFtYmRhSW5zdHJ1bWVudGF0aW9uUHJvcHMgZXh0ZW5kcyBPZGlnb3NJbnN0cnVtZW50YXRpb25PcHRpb25zIHtcbiAgLyoqXG4gICAqIEZ1bmN0aW9ucyB0byBpbnN0cnVtZW50IG9uIGNvbnN0cnVjdGlvbi4gTW9yZSBjYW4gYmUgYWRkZWQgd2l0aCBgaW5zdHJ1bWVudCgpYC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBub25lXG4gICAqL1xuICByZWFkb25seSBmdW5jdGlvbnM/OiBsYW1iZGEuRnVuY3Rpb25bXTtcbn1cblxuLyoqXG4gKiBJbnN0cnVtZW50cyBBV1MgTGFtYmRhIGZ1bmN0aW9ucyB3aXRoIHRoZSBPZGlnb3MgT3BlblRlbGVtZXRyeSBsYXllci5cbiAqXG4gKiBgYGB0c1xuICogY29uc3Qgb2RpZ29zID0gbmV3IE9kaWdvc0xhbWJkYUluc3RydW1lbnRhdGlvbih0aGlzLCAnT2RpZ29zJywge1xuICogICBkZXN0aW5hdGlvbjogeyBlbmRwb2ludDogJ290bHAuZXhhbXBsZS5jb206NDMxNycgfSxcbiAqICAgZnVuY3Rpb25zOiBbYXBpRm4sIHdvcmtlckZuXSxcbiAqIH0pO1xuICogb2RpZ29zLmluc3RydW1lbnQoYW5vdGhlckZuKTtcbiAqIGBgYFxuICpcbiAqIFdoYXQgaXQgZG9lcyB0byBlYWNoIGZ1bmN0aW9uOiBhdHRhY2hlcyB0aGUgbGF5ZXIgZm9yIHRoZSBmdW5jdGlvbidzIGxhbmd1YWdlIGFuZCBhcmNoaXRlY3R1cmUsIHNldHNcbiAqIGBBV1NfTEFNQkRBX0VYRUNfV1JBUFBFUmAgc28gdGhlIGxheWVyIGxvYWRzIHRoZSBTREssIHNldHMgYE9URUxfU0VSVklDRV9OQU1FYCwgYW5kIGhhbmRzIHRoZSBpbi1MYW1iZGFcbiAqIGNvbGxlY3RvciBpdHMgZW50aXJlIGNvbmZpZ3VyYXRpb24gaW5saW5lIHRocm91Z2ggYE9QRU5URUxFTUVUUllfQ09MTEVDVE9SX0NPTkZJR19VUklgLlxuICpcbiAqIFRoZSBmdW5jdGlvbidzIFNESyBleHBvcnRzIHRvIHRoZSBjb2xsZWN0b3Igb24gbG9jYWxob3N0LCBub3QgdG8geW91ciBkZXN0aW5hdGlvbi4gVGhlIGNvbGxlY3RvclxuICogZm9yd2FyZHMgYWZ0ZXIgdGhlIGhhbmRsZXIgaGFzIGFscmVhZHkgcmV0dXJuZWQsIHNvIGEgc2xvdyBkZXN0aW5hdGlvbiBjb3N0cyBiaWxsZWQgZHVyYXRpb24gcmF0aGVyXG4gKiB0aGFuIGNhbGxlciBsYXRlbmN5LlxuICpcbiAqICMjIERvIG5vdCBhbHNvIGluc3RydW1lbnQgdGhlc2UgZnVuY3Rpb25zIHdpdGggdGhlIGNvbm5lY3RvclxuICpcbiAqIFRoZSBPZGlnb3MgQVdTIGNvbm5lY3RvciBpbnN0cnVtZW50cyBsaXZlIGZ1bmN0aW9ucyBieSBtdXRhdGluZyB0aGVtLCBhbmQgcmVjb25jaWxlcyB0aGVtIGJhY2sgdG8gaXRzXG4gKiBvd24gZGVzaXJlZCBzdGF0ZSBvbiBldmVyeSBwYXNzLiBBIGZ1bmN0aW9uIGluc3RydW1lbnRlZCBoZXJlIGFuZCBhbHNvIGVuYWJsZWQgYXMgYSBjb25uZWN0b3Igc291cmNlXG4gKiBlbmRzIHVwIG93bmVkIGJ5IGJvdGg6IGVhY2ggYGNkayBkZXBsb3lgIHJlYXNzZXJ0cyB0aGUgQ0RLJ3MgZW52aXJvbm1lbnQsIGVhY2ggcmVjb25jaWxlIHJlYXNzZXJ0cyB0aGVcbiAqIGNvbm5lY3RvcidzLCBhbmQgZXZlcnkgcm91bmQgdHJpcCBwdWJsaXNoZXMgYSBuZXcgZnVuY3Rpb24gdmVyc2lvbi5cbiAqXG4gKiBDaG9vc2Ugb25lIHBlciBmdW5jdGlvbi4gVGhpcyBjb25zdHJ1Y3QgbmV2ZXIgc2V0cyB0aGUgY29ubmVjdG9yJ3MgYE9ESUdPU19NQU5BR0VEYCBvd25lcnNoaXAgbWFya2VyLFxuICogc28gYW4gSWFDLWluc3RydW1lbnRlZCBmdW5jdGlvbiBpcyBub3Qgb25lIHRoZSBjb25uZWN0b3Igd2lsbCByb2xsIGJhY2sg4oCUIGJ1dCBpdCB3aWxsIGhhcHBpbHkgdGFrZSBpdFxuICogb3ZlciBpZiB5b3UgZW5hYmxlIGl0IGFzIGEgc291cmNlLlxuICovXG5leHBvcnQgY2xhc3MgT2RpZ29zTGFtYmRhSW5zdHJ1bWVudGF0aW9uIGV4dGVuZHMgQ29uc3RydWN0IHtcbiAgcHJpdmF0ZSByZWFkb25seSBvcHRpb25zOiBPZGlnb3NJbnN0cnVtZW50YXRpb25PcHRpb25zO1xuICBwcml2YXRlIHJlYWRvbmx5IHJlc29sdmVyOiBPZGlnb3NMYXllclJlc29sdmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IGNvbGxlY3RvckNvbmZpZzogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IGluc3RydW1lbnRlZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBPZGlnb3NMYW1iZGFJbnN0cnVtZW50YXRpb25Qcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICB0aGlzLm9wdGlvbnMgPSBwcm9wcztcbiAgICB0aGlzLnJlc29sdmVyID0gbmV3IE9kaWdvc0xheWVyUmVzb2x2ZXIodGhpcywgcHJvcHMubGF5ZXJTb3VyY2UgPz8gT2RpZ29zTGF5ZXJTb3VyY2UuT0RJR09TX1BVQkxJQyk7XG5cbiAgICAvLyBSZW5kZXJlZCBvbmNlLiBJdCBkZXBlbmRzIG9ubHkgb24gdGhlIGRlc3RpbmF0aW9uLCBhbmQgcmVuZGVyaW5nIGl0IHBlciBmdW5jdGlvbiB3b3VsZCBtYWtlIGFuXG4gICAgLy8gYWNjaWRlbnRhbCBkaWZmZXJlbmNlIGJldHdlZW4gdHdvIGZ1bmN0aW9ucyBwb3NzaWJsZS5cbiAgICB0aGlzLmNvbGxlY3RvckNvbmZpZyA9IHJlbmRlckNvbGxlY3RvckNvbmZpZyhwcm9wcy5kZXN0aW5hdGlvbik7XG5cbiAgICBmb3IgKGNvbnN0IGZuIG9mIHByb3BzLmZ1bmN0aW9ucyA/PyBbXSkge1xuICAgICAgdGhpcy5pbnN0cnVtZW50KGZuKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSW5zdHJ1bWVudHMgb25lIGZ1bmN0aW9uLiBJZGVtcG90ZW50IOKAlCBpbnN0cnVtZW50aW5nIHRoZSBzYW1lIGZ1bmN0aW9uIHR3aWNlIGlzIGEgbm8tb3AgcmF0aGVyIHRoYW4gYVxuICAgKiBkb3VibGVkIGxvYWRlciB2YWx1ZS5cbiAgICovXG4gIHB1YmxpYyBpbnN0cnVtZW50KGZuOiBsYW1iZGEuRnVuY3Rpb24pOiB2b2lkIHtcbiAgICBjb25zdCBrZXkgPSBmbi5ub2RlLnBhdGg7XG4gICAgaWYgKHRoaXMuaW5zdHJ1bWVudGVkLmhhcyhrZXkpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcnVudGltZU5hbWUgPSBmbi5ydW50aW1lLm5hbWU7XG4gICAgY29uc3QgbGFuZ3VhZ2UgPSBsYW5ndWFnZUZyb21SdW50aW1lKHJ1bnRpbWVOYW1lKTtcbiAgICBpZiAoIWxhbmd1YWdlKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID1cbiAgICAgICAgYE9kaWdvczogcnVudGltZSBcIiR7cnVudGltZU5hbWV9XCIgaGFzIG5vIE9wZW5UZWxlbWV0cnkgTGFtYmRhIGxheWVyIGAgK1xuICAgICAgICAnKHVwc3RyZWFtIHB1Ymxpc2hlcyBsYXllcnMgZm9yIHB5dGhvbiwgbm9kZWpzLCBqYXZhIGFuZCBydWJ5IG9ubHkpLCBzbyB0aGlzIGZ1bmN0aW9uIGNhbm5vdCBiZSBpbnN0cnVtZW50ZWQuJztcbiAgICAgIGlmICh0aGlzLm9wdGlvbnMuc2tpcFVuc3VwcG9ydGVkUnVudGltZXMpIHtcbiAgICAgICAgQW5ub3RhdGlvbnMub2YoZm4pLmFkZFdhcm5pbmdWMignQG9kaWdvcy9hd3MtY2RrOnVuc3VwcG9ydGVkUnVudGltZScsIGAke21lc3NhZ2V9IFNraXBwaW5nLmApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7bWVzc2FnZX0gU2V0IHNraXBVbnN1cHBvcnRlZFJ1bnRpbWVzOiB0cnVlIHRvIHNraXAgaXQgaW5zdGVhZC5gKTtcbiAgICB9XG5cbiAgICB0aGlzLmluc3RydW1lbnRlZC5hZGQoa2V5KTtcblxuICAgIGNvbnN0IGFyY2hpdGVjdHVyZSA9IGZuLmFyY2hpdGVjdHVyZS5uYW1lO1xuICAgIGNvbnN0IGxheWVyID0gdGhpcy5vcHRpb25zLmxheWVyVmVyc2lvbiA/PyB0aGlzLnJlc29sdmVyLnJlc29sdmUobGFuZ3VhZ2UsIGFyY2hpdGVjdHVyZSk7XG4gICAgZm4uYWRkTGF5ZXJzKGxheWVyKTtcblxuICAgIGZvciAoY29uc3QgW25hbWUsIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyh0aGlzLmVudmlyb25tZW50Rm9yKGZuLCBsYW5ndWFnZSkpKSB7XG4gICAgICBmbi5hZGRFbnZpcm9ubWVudChuYW1lLCB2YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqIEluc3RydW1lbnRzIGV2ZXJ5IGZ1bmN0aW9uIGluIHRoZSBsaXN0LiAqL1xuICBwdWJsaWMgaW5zdHJ1bWVudEFsbChmdW5jdGlvbnM6IGxhbWJkYS5GdW5jdGlvbltdKTogdm9pZCB7XG4gICAgZm9yIChjb25zdCBmbiBvZiBmdW5jdGlvbnMpIHtcbiAgICAgIHRoaXMuaW5zdHJ1bWVudChmbik7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBlbnZpcm9ubWVudCBhcHBsaWVkIHRvIG9uZSBmdW5jdGlvbi5cbiAgICpcbiAgICogTWlycm9ycyBgYXBwbHlIYW5kbGVyRW52YCAvIGBhcHBseVdlYlNlcnZlckVudmAgaW4gdGhlIGNvbm5lY3RvciwgaW5jbHVkaW5nIHdoYXQgaXMgZGVsaWJlcmF0ZWx5IE5PVFxuICAgKiBzZXQ6IGBPVEVMX0VYUE9SVEVSX09UTFBfRU5EUE9JTlRgIHN0YXlzIHVuc2V0IHNvIHRoZSBTREsga2VlcHMgZXhwb3J0aW5nIHRvIHRoZSBpbi1MYW1iZGEgY29sbGVjdG9yXG4gICAqIG9uIGxvY2FsaG9zdCByYXRoZXIgdGhhbiBibG9ja2luZyB0aGUgaW52b2NhdGlvbiBvbiB0aGUgcmVtb3RlIGRlc3RpbmF0aW9uLCBhbmQgYW4gZW5hYmxlZCBzaWduYWwnc1xuICAgKiBgT1RFTF8qX0VYUE9SVEVSYCBzdGF5cyB1bnNldCBiZWNhdXNlIGBvdGxwYCBpcyBhbHJlYWR5IHRoZSBTREsgZGVmYXVsdC5cbiAgICovXG4gIHByaXZhdGUgZW52aXJvbm1lbnRGb3IoZm46IGxhbWJkYS5GdW5jdGlvbiwgbGFuZ3VhZ2U6IHN0cmluZyk6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0ge1xuICAgIGNvbnN0IHsgZGVzdGluYXRpb24sIG1vZGUsIGRlYnVnLCBzZXJ2aWNlTmFtZSwgamF2YUhhbmRsZXJEaXN0cm8sIGV4aXN0aW5nTG9hZGVyVmFsdWUgfSA9IHRoaXMub3B0aW9ucztcbiAgICBjb25zdCB3ZWJTZXJ2ZXIgPSBtb2RlID09PSBPZGlnb3NJbnN0cnVtZW50YXRpb25Nb2RlLldFQl9TRVJWRVI7XG5cbiAgICBjb25zdCBlbnY6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0gPSB7XG4gICAgICBbRU5WX1NFUlZJQ0VfTkFNRV06IHNlcnZpY2VOYW1lID8/IGRlZmF1bHRTZXJ2aWNlTmFtZShmbiksXG4gICAgICBbRU5WX0NPTExFQ1RPUl9DT05GSUdfVVJJXTogdGhpcy5jb2xsZWN0b3JDb25maWcsXG4gICAgICBbRU5WX0lBQ19NQVJLRVJdOiBKU09OLnN0cmluZ2lmeSh7IHY6IDEsIHNvdXJjZTogJ2NkaycsIHZlcnNpb246IE9ESUdPU19WRVJTSU9OIHx8ICd1bnJlbGVhc2VkJyB9KSxcbiAgICB9O1xuXG4gICAgaWYgKHdlYlNlcnZlcikge1xuICAgICAgLy8gTm8gZXhlYyB3cmFwcGVyOiB0aGUgTGFtYmRhIFdlYiBBZGFwdGVyIG93bnMgaXQsIGFuZCBvdmVyd3JpdGluZyBpdCBzdG9wcyB0aGUgZnVuY3Rpb24gc2VydmluZy5cbiAgICAgIE9iamVjdC5hc3NpZ24oZW52LCB3ZWJTZXJ2ZXJFbnYobGFuZ3VhZ2UsIGV4aXN0aW5nTG9hZGVyVmFsdWUpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZW52W0VOVl9FWEVDX1dSQVBQRVJdID0gZXhlY1dyYXBwZXJGb3IobGFuZ3VhZ2UsIGphdmFIYW5kbGVyRGlzdHJvKTtcbiAgICAgIGlmIChkZWJ1Zykge1xuICAgICAgICBlbnZbRU5WX09URUxfTE9HX0xFVkVMXSA9ICdkZWJ1Zyc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gU3VwcHJlc3MgdGhlIHNpZ25hbHMgdGhlIGRlc3RpbmF0aW9uIGRvZXMgbm90IGFjY2VwdC4gQSBzaWduYWwgd2l0aCBubyBjb2xsZWN0b3IgcGlwZWxpbmUgaXMgcmVmdXNlZFxuICAgIC8vIGF0IHRoZSByZWNlaXZlciBvbiBldmVyeSBiYXRjaCwgc28gdGVsbGluZyB0aGUgU0RLIG5vdCB0byBwcm9kdWNlIGl0IGlzIHRoZSBoYWxmIHRoYXQgc3RvcHMgdGhlXG4gICAgLy8gZXJyb3IgbG9vcDsgdGhlIHBpcGVsaW5lIGJlaW5nIGFic2VudCBpcyB0aGUgaGFsZiB0aGF0IHN0b3BzIHRoZSBleHBvcnQuXG4gICAgY29uc3Qgb3ZlcnJpZGVzOiBBcnJheTxbc3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWRdPiA9IFtcbiAgICAgIFtFTlZfVFJBQ0VTX0VYUE9SVEVSLCBleHBvcnRlck92ZXJyaWRlRm9yKHNpZ25hbEVuYWJsZWQoZGVzdGluYXRpb24udHJhY2VzKSldLFxuICAgICAgW0VOVl9NRVRSSUNTX0VYUE9SVEVSLCBleHBvcnRlck92ZXJyaWRlRm9yKHNpZ25hbEVuYWJsZWQoZGVzdGluYXRpb24ubWV0cmljcykpXSxcbiAgICAgIFtFTlZfTE9HU19FWFBPUlRFUiwgZXhwb3J0ZXJPdmVycmlkZUZvcihzaWduYWxFbmFibGVkKGRlc3RpbmF0aW9uLmxvZ3MpKV0sXG4gICAgXTtcbiAgICBmb3IgKGNvbnN0IFtuYW1lLCB2YWx1ZV0gb2Ygb3ZlcnJpZGVzKSB7XG4gICAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBlbnZbbmFtZV0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZW52O1xuICB9XG59XG5cbi8qKlxuICogUHJvcHMgZm9yIHtAbGluayBPZGlnb3NJbnN0cnVtZW50YXRpb25Bc3BlY3R9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE9kaWdvc0luc3RydW1lbnRhdGlvbkFzcGVjdFByb3BzIGV4dGVuZHMgT2RpZ29zSW5zdHJ1bWVudGF0aW9uT3B0aW9ucyB7fVxuXG4vKipcbiAqIEFwcGxpZXMgT2RpZ29zIGluc3RydW1lbnRhdGlvbiB0byBldmVyeSBgbGFtYmRhLkZ1bmN0aW9uYCBpbiBhIHNjb3BlLlxuICpcbiAqIGBgYHRzXG4gKiBBc3BlY3RzLm9mKHN0YWNrKS5hZGQobmV3IE9kaWdvc0luc3RydW1lbnRhdGlvbkFzcGVjdChzdGFjaywge1xuICogICBkZXN0aW5hdGlvbjogeyBlbmRwb2ludDogJ290bHAuZXhhbXBsZS5jb206NDMxNycgfSxcbiAqIH0pKTtcbiAqIGBgYFxuICpcbiAqIGBza2lwVW5zdXBwb3J0ZWRSdW50aW1lc2AgZGVmYXVsdHMgdG8gYHRydWVgIGhlcmUsIHVubGlrZSB0aGUgY29uc3RydWN0OiBhbiBhc3BlY3QgdmlzaXRzIGV2ZXJ5IGZ1bmN0aW9uXG4gKiBpbiB0aGUgc2NvcGUsIGluY2x1ZGluZyBvbmVzIHdob3NlIHJ1bnRpbWUgaGFzIG5vIE9wZW5UZWxlbWV0cnkgbGF5ZXIsIGFuZCBmYWlsaW5nIHRoZSB3aG9sZSBzeW50aFxuICogYmVjYXVzZSBhIHN0YWNrIGhhcHBlbnMgdG8gY29udGFpbiBvbmUgR28gZnVuY3Rpb24gaXMgbm90IHVzZWZ1bC4gRWFjaCBza2lwIGlzIHJlcG9ydGVkIGFzIGEgc3ludGhcbiAqIHdhcm5pbmcsIHNvIGl0IGlzIHZpc2libGUgcmF0aGVyIHRoYW4gc2lsZW50LlxuICpcbiAqIFRoZSBhc3BlY3QgaW5zdHJ1bWVudHMgd2hhdCBleGlzdHMgaW4gdGhlIHRyZWUgd2hlbiBpdCBydW5zLiBBIGZ1bmN0aW9uIGFkZGVkIGJ5IGEgbGF0ZXIgYXNwZWN0IGlzIG5vdFxuICogdmlzaXRlZDsgdXNlIHRoZSBjb25zdHJ1Y3QgZGlyZWN0bHkgZm9yIHRob3NlLlxuICovXG5leHBvcnQgY2xhc3MgT2RpZ29zSW5zdHJ1bWVudGF0aW9uQXNwZWN0IGltcGxlbWVudHMgSUFzcGVjdCB7XG4gIHByaXZhdGUgcmVhZG9ubHkgaW5zdHJ1bWVudGF0aW9uOiBPZGlnb3NMYW1iZGFJbnN0cnVtZW50YXRpb247XG5cbiAgLyoqXG4gICAqIEBwYXJhbSBzY29wZSB3aGVyZSB0aGUgc2hhcmVkIGxheWVyIGNvbnN0cnVjdHMgYXJlIGNyZWF0ZWQuIFVzdWFsbHkgdGhlIHNhbWUgc2NvcGUgdGhlIGFzcGVjdCBpc1xuICAgKiBhcHBsaWVkIHRvLiBJdCBpcyBhIHNlcGFyYXRlIGFyZ3VtZW50IGZyb20gdGhlIHZpc2l0ZWQgbm9kZXMgYmVjYXVzZSB0aGUgbGF5ZXIgKGFuZCwgaW4gYElOX0FDQ09VTlRgXG4gICAqIG1vZGUsIHRoZSBuZXN0ZWQgU0FSIGFwcGxpY2F0aW9uKSBpcyBjcmVhdGVkIG9uY2UgYW5kIHNoYXJlZCBieSBldmVyeSBmdW5jdGlvbiB0aGUgYXNwZWN0IHZpc2l0cy5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIHByb3BzOiBPZGlnb3NJbnN0cnVtZW50YXRpb25Bc3BlY3RQcm9wcykge1xuICAgIHRoaXMuaW5zdHJ1bWVudGF0aW9uID0gbmV3IE9kaWdvc0xhbWJkYUluc3RydW1lbnRhdGlvbihzY29wZSwgJ09kaWdvc0luc3RydW1lbnRhdGlvbkFzcGVjdCcsIHtcbiAgICAgIHNraXBVbnN1cHBvcnRlZFJ1bnRpbWVzOiB0cnVlLFxuICAgICAgLi4ucHJvcHMsXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgdmlzaXQobm9kZTogSUNvbnN0cnVjdCk6IHZvaWQge1xuICAgIGlmIChub2RlIGluc3RhbmNlb2YgbGFtYmRhLkZ1bmN0aW9uKSB7XG4gICAgICB0aGlzLmluc3RydW1lbnRhdGlvbi5pbnN0cnVtZW50KG5vZGUpO1xuICAgIH1cbiAgfVxufVxuIl19
@@ -0,0 +1,46 @@
1
+ import * as lambda from 'aws-cdk-lib/aws-lambda';
2
+ import { Construct } from 'constructs';
3
+ import { OdigosLayerSource } from './types';
4
+ /**
5
+ * Resolves the Odigos layer for a (language, architecture) to an `ILayerVersion`, and caches it so N
6
+ * functions of the same language and architecture share one layer construct — and, in `IN_ACCOUNT` mode,
7
+ * one nested SAR application rather than N copies of the same layer.
8
+ */
9
+ export declare class OdigosLayerResolver {
10
+ private readonly scope;
11
+ private readonly source;
12
+ private readonly cache;
13
+ constructor(scope: Construct, source: OdigosLayerSource);
14
+ resolve(language: string, architecture: string): lambda.ILayerVersion;
15
+ /**
16
+ * The public layer version Odigos published in this stack's region, resolved from the table baked into
17
+ * this package at build time.
18
+ *
19
+ * A region with no entry throws rather than falling back to another region's ARN, which would not
20
+ * resolve, or to no layer, which would leave the function reporting healthy and exporting nothing.
21
+ */
22
+ private fromPublicArn;
23
+ /**
24
+ * Deploys the Odigos SAR application into this account as a nested stack and attaches the layer it
25
+ * creates.
26
+ *
27
+ * Pinning `semanticVersion` is what makes this reproducible: a SAR application version is immutable, so
28
+ * the pinned version resolves to the same layer bytes forever. Leaving it unpinned would let a later
29
+ * `cdk deploy` of unchanged code pick up a different layer.
30
+ */
31
+ private fromSar;
32
+ /** `Python_X8664` — a construct-id-safe suffix that keeps ids stable and readable in the template. */
33
+ private constructSuffix;
34
+ }
35
+ /**
36
+ * The layer name this package attaches, exposed so a stack can assert on it or build an allowlist.
37
+ *
38
+ * Deliberately identical to the name the connector publishes into an account
39
+ * (`store.OdigosLayerNamePrefix` + language + "-" + architecture). That is what lets a function
40
+ * instrumented here and later enabled as a connector source converge: the connector sees the same layer
41
+ * NAME, swaps its own version in rather than attaching a second OpenTelemetry layer, and recognises the
42
+ * layer as one it may manage.
43
+ */
44
+ export declare function odigosLayerName(language: string, architecture: string): string;
45
+ /** Stable, human-readable construct id fragment for a function. Exported for the aspect. */
46
+ export declare function functionScopeId(fn: Construct): string;