@reventlessdev/reventless-aws 3.0.0-alpha.172 → 3.0.0-alpha.174
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/CHANGELOG.md +20 -0
- package/package.json +6 -6
- package/src/Platform.res +77 -7
- package/src/Platform.res.mjs +82 -8
- package/src/adapter/Counter/CounterHandler_DynamoDbStream.res.mjs +1 -1
- package/src/adapter/DcbEventLog/DcbBackend.res +78 -0
- package/src/adapter/DcbEventLog/DcbBackend.res.mjs +53 -0
- package/src/adapter/DcbEventLog/DcbEventLogStorage.res +20 -0
- package/src/adapter/DcbEventLog/DcbEventLogStorage.res.mjs +21 -1
- package/src/adapter/DcbEventLog/DcbEventLogStorage_Postgres.res +43 -0
- package/src/adapter/DcbEventLog/DcbEventLogStorage_Postgres.res.mjs +21 -0
- package/src/adapter/DcbEventLog/DcbEventLogStorage_Postgres_Runtime.res +26 -0
- package/src/adapter/DcbEventLog/DcbEventLogStorage_Postgres_Runtime.res.mjs +15 -0
- package/src/adapter/EventLog/EventLogStorage_Postgres_Runtime.res +23 -0
- package/src/adapter/EventLog/EventLogStorage_Postgres_Runtime.res.mjs +14 -0
- package/src/adapter/Postgres/PgChangeFeedRelay_Builder.res +188 -0
- package/src/adapter/Postgres/PgChangeFeedRelay_Builder.res.mjs +141 -0
- package/src/adapter/Postgres/PgChangeFeedRelay_Runtime.res +72 -0
- package/src/adapter/Postgres/PgChangeFeedRelay_Runtime.res.mjs +40 -0
- package/src/adapter/Runtime/AggregateEntryPoint.mjs +27 -9
- package/src/adapter/Runtime/AggregateRuntime_Builder_Micro.res.mjs +3 -3
- package/src/adapter/Runtime/AggregateRuntime_Builder_Micro_Async.res.mjs +3 -3
- package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate.res.mjs +1 -1
- package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate_Async.res.mjs +1 -1
- package/src/adapter/Runtime/AggregateRuntime_Builder_Single.res.mjs +1 -1
- package/src/adapter/Runtime/AggregateRuntime_Builder_Single_Async.res.mjs +1 -1
- package/src/adapter/Runtime/AutomationSliceRuntime_Builder_Single.res.mjs +1 -1
- package/src/adapter/Runtime/DcbCommandTopicEntryPoint.mjs +20 -6
- package/src/adapter/Runtime/EventCollectorRuntime_Builder_PerEventCollector.res.mjs +1 -1
- package/src/adapter/Runtime/EventCollectorRuntime_Builder_Single.res.mjs +1 -1
- package/src/adapter/Runtime/ExtensionPointRuntime_Builder_PerExtensionPoint.res.mjs +1 -1
- package/src/adapter/Runtime/PgChangeFeedRelayEntryPoint.mjs +52 -0
- package/src/adapter/Runtime/RuntimeEnvironment_Lambda.res +38 -0
- package/src/adapter/Runtime/RuntimeEnvironment_Lambda.res.mjs +20 -2
- package/src/adapter/Runtime/SideEffectHandlerRuntime_Builder_Single.res.mjs +1 -1
- package/src/adapter/Runtime/StateChangeSliceRuntime_Builder_Single.res +84 -6
- package/src/adapter/Runtime/StateChangeSliceRuntime_Builder_Single.res.mjs +49 -4
- package/src/adapter/Runtime/StateViewSliceRuntime_Builder_Single.res.mjs +1 -1
- package/src/adapter/Runtime/TaskRuntime_Builder_PerBucket.res.mjs +1 -1
- package/src/components/Api/AppSync_Adapter.res +72 -8
- package/src/components/Api/AppSync_Adapter.res.mjs +45 -6
- package/src/components/Plugin.res +1 -1
- package/src/components/Plugin.res.mjs +2 -2
- package/src/plugin/runtime/PluginExtensionPointRuntime_Builder.res.mjs +1 -1
- package/src/plugin/runtime/PluginRuntime_Builder.res +20 -0
- package/src/plugin/runtime/PluginRuntime_Builder.res.mjs +10 -2
- package/tests/AppSync_AdapterTest.res +140 -0
- package/tests/AppSync_AdapterTest.res.mjs +182 -6
- package/tests/PgChangeFeedRelay_RuntimeTest.res +75 -0
- package/tests/PgChangeFeedRelay_RuntimeTest.res.mjs +135 -0
|
@@ -173,7 +173,7 @@ function finish() {
|
|
|
173
173
|
cmdTopicEnvVars["HANDLER_CONFIG"] = cmdTopicHandlerConfigOutput;
|
|
174
174
|
let match = Util_Bundle$ReventlessAws.buildCodeArchive("@reventlessdev/reventless-aws/src/adapter/Runtime/AggregateEntryPoint.mjs", packageDirs, undefined);
|
|
175
175
|
let cmdTopicName = baseName + "CmdHandler";
|
|
176
|
-
let cmdTopicRuntime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(cmdTopicName, match.code, match.sourceCodeHash, cmdTopicEnvVars, Math.max(spec.commandTopicMemorySize, 1024), Math.max(spec.commandTopicTimeout, 30), undefined, undefined, undefined, undefined, aggregateOpts);
|
|
176
|
+
let cmdTopicRuntime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(cmdTopicName, match.code, match.sourceCodeHash, cmdTopicEnvVars, Math.max(spec.commandTopicMemorySize, 1024), Math.max(spec.commandTopicTimeout, 30), undefined, undefined, undefined, undefined, undefined, aggregateOpts);
|
|
177
177
|
spec.commandTopicConnects.forEach(connect => connect(cmdTopicRuntime));
|
|
178
178
|
if (spec.commandGeneratorConnects.length !== 0) {
|
|
179
179
|
let cmdGenHandlerConfigOutput = Pulumi.all([
|
|
@@ -185,7 +185,7 @@ function finish() {
|
|
|
185
185
|
cmdGenEnvVars["HANDLER_CONFIG"] = cmdGenHandlerConfigOutput;
|
|
186
186
|
let match$1 = Util_Bundle$ReventlessAws.buildCodeArchive("@reventlessdev/reventless-aws/src/adapter/Runtime/AggregateEntryPoint.mjs", packageDirs, undefined);
|
|
187
187
|
let cmdGenName = baseName + "CmdGen";
|
|
188
|
-
let cmdGenRuntime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(cmdGenName, match$1.code, match$1.sourceCodeHash, cmdGenEnvVars, Math.max(spec.commandGeneratorMemorySize, 1024), Math.max(spec.commandGeneratorTimeout, 30), undefined, undefined, undefined, undefined, aggregateOpts);
|
|
188
|
+
let cmdGenRuntime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(cmdGenName, match$1.code, match$1.sourceCodeHash, cmdGenEnvVars, Math.max(spec.commandGeneratorMemorySize, 1024), Math.max(spec.commandGeneratorTimeout, 30), undefined, undefined, undefined, undefined, undefined, aggregateOpts);
|
|
189
189
|
spec.commandGeneratorConnects.forEach(connect => connect(cmdGenRuntime));
|
|
190
190
|
}
|
|
191
191
|
let match$2 = spec.eventCollectorChannelSpec;
|
|
@@ -208,7 +208,7 @@ function finish() {
|
|
|
208
208
|
evtMapperPackageDirs[mappingsPkg] = Util_Bundle$ReventlessAws.resolvePackageRoot(mappingsPkg);
|
|
209
209
|
let match$4 = Util_Bundle$ReventlessAws.buildCodeArchive("@reventlessdev/reventless-aws/src/adapter/Runtime/EventMapperEntryPoint.mjs", evtMapperPackageDirs, undefined);
|
|
210
210
|
let evtMapperName = baseName + "EventMapper";
|
|
211
|
-
let evtMapperRuntime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(evtMapperName, match$4.code, match$4.sourceCodeHash, evtMapperEnvVars, Math.max(spec.eventCollectorMemorySize, 2048), Math.max(spec.eventCollectorTimeout, 180), undefined, undefined, undefined, undefined, aggregateOpts);
|
|
211
|
+
let evtMapperRuntime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(evtMapperName, match$4.code, match$4.sourceCodeHash, evtMapperEnvVars, Math.max(spec.eventCollectorMemorySize, 2048), Math.max(spec.eventCollectorTimeout, 180), undefined, undefined, undefined, undefined, undefined, aggregateOpts);
|
|
212
212
|
EventCollectorChannel_DynamoDbStream$ReventlessAws.connect(evtMapperName, [match$2], evtMapperRuntime, aggregateOpts);
|
|
213
213
|
});
|
|
214
214
|
}
|
|
@@ -173,7 +173,7 @@ function finish() {
|
|
|
173
173
|
cmdTopicEnvVars["HANDLER_CONFIG"] = cmdTopicHandlerConfigOutput;
|
|
174
174
|
let match = Util_Bundle$ReventlessAws.buildCodeArchive("@reventlessdev/reventless-aws/src/adapter/Runtime/AggregateEntryPoint.mjs", packageDirs, undefined);
|
|
175
175
|
let cmdTopicName = baseName + "CmdHandler";
|
|
176
|
-
let cmdTopicRuntime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(cmdTopicName, match.code, match.sourceCodeHash, cmdTopicEnvVars, Math.max(spec.commandTopicMemorySize, 1024), Math.max(spec.commandTopicTimeout, 30), undefined, undefined, undefined, undefined, aggregateOpts);
|
|
176
|
+
let cmdTopicRuntime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(cmdTopicName, match.code, match.sourceCodeHash, cmdTopicEnvVars, Math.max(spec.commandTopicMemorySize, 1024), Math.max(spec.commandTopicTimeout, 30), undefined, undefined, undefined, undefined, undefined, aggregateOpts);
|
|
177
177
|
spec.commandTopicConnects.forEach(connect => connect(cmdTopicRuntime));
|
|
178
178
|
if (spec.commandGeneratorConnects.length !== 0) {
|
|
179
179
|
let cmdGenHandlerConfigOutput = Pulumi.all([
|
|
@@ -186,7 +186,7 @@ function finish() {
|
|
|
186
186
|
cmdGenEnvVars["DISPATCH_MODE"] = "async";
|
|
187
187
|
let match$1 = Util_Bundle$ReventlessAws.buildCodeArchive("@reventlessdev/reventless-aws/src/adapter/Runtime/AggregateEntryPoint.mjs", packageDirs, undefined);
|
|
188
188
|
let cmdGenName = baseName + "CmdGen";
|
|
189
|
-
let cmdGenRuntime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(cmdGenName, match$1.code, match$1.sourceCodeHash, cmdGenEnvVars, Math.max(spec.commandGeneratorMemorySize, 1024), Math.max(spec.commandGeneratorTimeout, 30), undefined, undefined, undefined, undefined, aggregateOpts);
|
|
189
|
+
let cmdGenRuntime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(cmdGenName, match$1.code, match$1.sourceCodeHash, cmdGenEnvVars, Math.max(spec.commandGeneratorMemorySize, 1024), Math.max(spec.commandGeneratorTimeout, 30), undefined, undefined, undefined, undefined, undefined, aggregateOpts);
|
|
190
190
|
spec.commandGeneratorConnects.forEach(connect => connect(cmdGenRuntime));
|
|
191
191
|
}
|
|
192
192
|
let match$2 = spec.eventCollectorChannelSpec;
|
|
@@ -209,7 +209,7 @@ function finish() {
|
|
|
209
209
|
evtMapperPackageDirs[mappingsPkg] = Util_Bundle$ReventlessAws.resolvePackageRoot(mappingsPkg);
|
|
210
210
|
let match$4 = Util_Bundle$ReventlessAws.buildCodeArchive("@reventlessdev/reventless-aws/src/adapter/Runtime/EventMapperEntryPoint.mjs", evtMapperPackageDirs, undefined);
|
|
211
211
|
let evtMapperName = baseName + "EventMapper";
|
|
212
|
-
let evtMapperRuntime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(evtMapperName, match$4.code, match$4.sourceCodeHash, evtMapperEnvVars, Math.max(spec.eventCollectorMemorySize, 2048), Math.max(spec.eventCollectorTimeout, 180), undefined, undefined, undefined, undefined, aggregateOpts);
|
|
212
|
+
let evtMapperRuntime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(evtMapperName, match$4.code, match$4.sourceCodeHash, evtMapperEnvVars, Math.max(spec.eventCollectorMemorySize, 2048), Math.max(spec.eventCollectorTimeout, 180), undefined, undefined, undefined, undefined, undefined, aggregateOpts);
|
|
213
213
|
EventCollectorChannel_DynamoDbStream$ReventlessAws.connect(evtMapperName, [match$2], evtMapperRuntime, aggregateOpts);
|
|
214
214
|
});
|
|
215
215
|
}
|
|
@@ -152,7 +152,7 @@ function finish() {
|
|
|
152
152
|
packageDirs[specPkg] = Util_Bundle$ReventlessAws.resolvePackageRoot(specPkg);
|
|
153
153
|
packageDirs[behaviorPkg] = Util_Bundle$ReventlessAws.resolvePackageRoot(behaviorPkg);
|
|
154
154
|
let match = Util_Bundle$ReventlessAws.buildCodeArchive("@reventlessdev/reventless-aws/src/adapter/Runtime/AggregateEntryPoint.mjs", packageDirs, undefined);
|
|
155
|
-
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(lambdaName, match.code, match.sourceCodeHash, envVars, spec.memorySize, spec.timeout, undefined, undefined, undefined, undefined, aggregateOpts);
|
|
155
|
+
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(lambdaName, match.code, match.sourceCodeHash, envVars, spec.memorySize, spec.timeout, undefined, undefined, undefined, undefined, undefined, aggregateOpts);
|
|
156
156
|
spec.connects.forEach(connect => connect(runtime));
|
|
157
157
|
let channelSpecs = Stdlib_Option.mapOr(spec.eventCollectorChannelSpec, [], cs => [cs]);
|
|
158
158
|
EventCollectorChannel_DynamoDbStream$ReventlessAws.connect(name, channelSpecs, runtime, aggregateOpts);
|
|
@@ -152,7 +152,7 @@ function finish() {
|
|
|
152
152
|
packageDirs[specPkg] = Util_Bundle$ReventlessAws.resolvePackageRoot(specPkg);
|
|
153
153
|
packageDirs[behaviorPkg] = Util_Bundle$ReventlessAws.resolvePackageRoot(behaviorPkg);
|
|
154
154
|
let match = Util_Bundle$ReventlessAws.buildCodeArchive("@reventlessdev/reventless-aws/src/adapter/Runtime/AggregateEntryPoint.mjs", packageDirs, undefined);
|
|
155
|
-
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(name, match.code, match.sourceCodeHash, envVars, spec.memorySize, spec.timeout, undefined, undefined, undefined, undefined, aggregateOpts);
|
|
155
|
+
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(name, match.code, match.sourceCodeHash, envVars, spec.memorySize, spec.timeout, undefined, undefined, undefined, undefined, undefined, aggregateOpts);
|
|
156
156
|
spec.connects.forEach(connect => connect(runtime));
|
|
157
157
|
let channelSpecs = Stdlib_Option.mapOr(spec.eventCollectorChannelSpec, [], cs => [cs]);
|
|
158
158
|
EventCollectorChannel_DynamoDbStream$ReventlessAws.connect(name, channelSpecs, runtime, aggregateOpts);
|
|
@@ -187,7 +187,7 @@ function finish() {
|
|
|
187
187
|
}));
|
|
188
188
|
let match = Util_Bundle$ReventlessAws.buildCodeArchive("@reventlessdev/reventless-aws/src/adapter/Runtime/AggregateEntryPoint.mjs", packageDirs, undefined);
|
|
189
189
|
Stdlib_Option.forEach(cfg.sqsBatchSize, CommandTopicChannel_SQS_Sync$ReventlessAws.setBatchSize);
|
|
190
|
-
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset("AllAggregatesCmdHandler", match.code, match.sourceCodeHash, envVars, cfg.memorySize, cfg.timeout, cfg.reservedConcurrency, cfg.ephemeralStorageMb, cfg.logRetentionDays, undefined, opts);
|
|
190
|
+
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset("AllAggregatesCmdHandler", match.code, match.sourceCodeHash, envVars, cfg.memorySize, cfg.timeout, cfg.reservedConcurrency, cfg.ephemeralStorageMb, cfg.logRetentionDays, undefined, undefined, opts);
|
|
191
191
|
let tableName$1 = pluginRmTableName.contents;
|
|
192
192
|
if (tableName$1 !== undefined) {
|
|
193
193
|
Pulumi.all([
|
|
@@ -174,7 +174,7 @@ function finish() {
|
|
|
174
174
|
}));
|
|
175
175
|
let match = Util_Bundle$ReventlessAws.buildCodeArchive("@reventlessdev/reventless-aws/src/adapter/Runtime/AggregateEntryPoint.mjs", packageDirs, undefined);
|
|
176
176
|
Stdlib_Option.forEach(cfg.sqsBatchSize, CommandTopicChannel_SQS_Async$ReventlessAws.setBatchSize);
|
|
177
|
-
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset("AllAggregatesAsyncCmdHandler", match.code, match.sourceCodeHash, envVars, cfg.memorySize, cfg.timeout, cfg.reservedConcurrency, cfg.ephemeralStorageMb, cfg.logRetentionDays, undefined, opts);
|
|
177
|
+
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset("AllAggregatesAsyncCmdHandler", match.code, match.sourceCodeHash, envVars, cfg.memorySize, cfg.timeout, cfg.reservedConcurrency, cfg.ephemeralStorageMb, cfg.logRetentionDays, undefined, undefined, opts);
|
|
178
178
|
specs.forEach(param => {
|
|
179
179
|
param.connects.forEach(connect => connect(runtime));
|
|
180
180
|
});
|
|
@@ -116,7 +116,7 @@ function finish() {
|
|
|
116
116
|
let envVars = {};
|
|
117
117
|
envVars["HANDLER_CONFIG"] = handlerConfigOutput;
|
|
118
118
|
let match$1 = Util_Bundle$ReventlessAws.buildCodeArchive("@reventlessdev/reventless-aws/src/adapter/Runtime/AutomationSliceEntryPoint.mjs", packageDirs, undefined);
|
|
119
|
-
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset("AllAutomationSlices", match$1.code, match$1.sourceCodeHash, envVars, match[0], match[1], undefined, undefined, undefined, undefined, opts);
|
|
119
|
+
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset("AllAutomationSlices", match$1.code, match$1.sourceCodeHash, envVars, match[0], match[1], undefined, undefined, undefined, undefined, undefined, opts);
|
|
120
120
|
let channelSpecs = storedSpecs.map(param => param.channelSpec);
|
|
121
121
|
EventCollectorChannel_DynamoDbStream$ReventlessAws.connect("AllAutomationSlices", channelSpecs, runtime, opts);
|
|
122
122
|
} else {
|
|
@@ -22,6 +22,7 @@ import { makeGenerateCommand } from "@reventlessdev/reventless-core/src/componen
|
|
|
22
22
|
import { commandOutcomeToJson, runInlineAndCollect } from "@reventlessdev/reventless-core/src/components/CommandTopic/CommandTopic_Helpers.res.mjs";
|
|
23
23
|
import { json as jsonSchema } from "sury/src/S.res.mjs";
|
|
24
24
|
import { read, append, readStream } from "@reventlessdev/reventless-aws/src/adapter/DcbEventLog/DcbEventLogStorage_DynamoDb_Runtime.res.mjs";
|
|
25
|
+
import { opsFor as pgDcbEventLogOpsFor } from "@reventlessdev/reventless-aws/src/adapter/DcbEventLog/DcbEventLogStorage_Postgres_Runtime.res.mjs";
|
|
25
26
|
import { handleQueueEvent, publishJsons as sqsPublishJsons } from "@reventlessdev/reventless-aws/src/adapter/CommandTopic/CommandTopicChannel_SQS_Runtime.res.mjs";
|
|
26
27
|
|
|
27
28
|
const dynamicImport = (specifier) => import('/var/task/node_modules/' + specifier);
|
|
@@ -90,12 +91,25 @@ function getIdStringSchema() {
|
|
|
90
91
|
// can drive the real `cmdGenHandler` end-to-end against DynamoDB Local.
|
|
91
92
|
export async function buildHandlersForConfig(config, opts = {}) {
|
|
92
93
|
const loadModule = opts.loadModule ?? dynamicImport;
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
94
|
+
// `pgConnection`, when present in HANDLER_CONFIG, selects the Postgres DCB
|
|
95
|
+
// runtime (dcbEventLogTableName doubles as the `dcb_event.log_name`); absence
|
|
96
|
+
// keeps the DynamoDB path byte-identical. NB: this swaps only the *storage*
|
|
97
|
+
// ops — event propagation (within-plugin projections + cross-plugin SNS) is
|
|
98
|
+
// stream-driven on AWS and is handled separately by the change-feed relay
|
|
99
|
+
// (see docs/plans/aws-postgres-change-feed-bridge.md), not by this Lambda.
|
|
100
|
+
const rawStorageOps = config.pgConnection
|
|
101
|
+
? (() => {
|
|
102
|
+
const pgOps = pgDcbEventLogOpsFor(config.pgConnection, config.dcbEventLogTableName);
|
|
103
|
+
return { read: pgOps.read, append: pgOps.append, readStream: pgOps.readStream };
|
|
104
|
+
})()
|
|
105
|
+
: (() => {
|
|
106
|
+
const resolvedTable = { name: config.dcbEventLogTableName };
|
|
107
|
+
return {
|
|
108
|
+
read: read(resolvedTable),
|
|
109
|
+
append: append(resolvedTable),
|
|
110
|
+
readStream: readStream(resolvedTable),
|
|
111
|
+
};
|
|
112
|
+
})();
|
|
99
113
|
|
|
100
114
|
const handlersByType = {};
|
|
101
115
|
const sharedDcbEventLogOps = dcbEventLogOperationsMake({
|
|
@@ -61,7 +61,7 @@ function forEventCollector(param, eventTopics, resources, memorySizeOpt, timeout
|
|
|
61
61
|
packageDirs[specPkg] = Util_Bundle$ReventlessAws.resolvePackageRoot(specPkg);
|
|
62
62
|
packageDirs[mappingsPkg] = Util_Bundle$ReventlessAws.resolvePackageRoot(mappingsPkg);
|
|
63
63
|
let match = Util_Bundle$ReventlessAws.buildCodeArchive("@reventlessdev/reventless-aws/src/adapter/Runtime/ReadModelEntryPoint.mjs", packageDirs, undefined);
|
|
64
|
-
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(name, match.code, match.sourceCodeHash, envVars, memorySize, timeout, undefined, undefined, undefined, undefined, opts);
|
|
64
|
+
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(name, match.code, match.sourceCodeHash, envVars, memorySize, timeout, undefined, undefined, undefined, undefined, undefined, opts);
|
|
65
65
|
EventCollectorChannel_DynamoDbStream$ReventlessAws.connect(name, [{
|
|
66
66
|
channel: channel,
|
|
67
67
|
eventTopics: eventTopics,
|
|
@@ -108,7 +108,7 @@ function finish() {
|
|
|
108
108
|
let envVars = {};
|
|
109
109
|
envVars["HANDLER_CONFIG"] = handlerConfigOutput;
|
|
110
110
|
let match$1 = Util_Bundle$ReventlessAws.buildCodeArchive("@reventlessdev/reventless-aws/src/adapter/Runtime/ReadModelEntryPoint.mjs", packageDirs, undefined);
|
|
111
|
-
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset("AllReadModels", match$1.code, match$1.sourceCodeHash, envVars, match[0], match[1], undefined, undefined, undefined, undefined, opts);
|
|
111
|
+
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset("AllReadModels", match$1.code, match$1.sourceCodeHash, envVars, match[0], match[1], undefined, undefined, undefined, undefined, undefined, opts);
|
|
112
112
|
let channelSpecs = storedSpecs.map(param => param.channelSpec);
|
|
113
113
|
EventCollectorChannel_DynamoDbStream$ReventlessAws.connect("AllReadModels", channelSpecs, runtime, opts);
|
|
114
114
|
} else {
|
|
@@ -39,7 +39,7 @@ function forCommandTopic(param, connect, memorySizeOpt, timeoutOpt, specModuleUr
|
|
|
39
39
|
packageDirs[specPkg] = Util_Bundle$ReventlessAws.resolvePackageRoot(specPkg);
|
|
40
40
|
packageDirs[mappingsPkg] = Util_Bundle$ReventlessAws.resolvePackageRoot(mappingsPkg);
|
|
41
41
|
let match = Util_Bundle$ReventlessAws.buildCodeArchive("@reventlessdev/reventless-aws/src/adapter/Runtime/ExtensionPointEntryPoint.mjs", packageDirs, undefined);
|
|
42
|
-
return connect(RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(name, match.code, match.sourceCodeHash, envVars, memorySize, timeout, undefined, undefined, undefined, undefined, opts));
|
|
42
|
+
return connect(RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(name, match.code, match.sourceCodeHash, envVars, memorySize, timeout, undefined, undefined, undefined, undefined, undefined, opts));
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
function finish() {
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// PgChangeFeedRelay Lambda entry point (scheduled poll — B2.3).
|
|
2
|
+
//
|
|
3
|
+
// Triggered on a schedule (EventBridge rate rule). Each invocation drains every
|
|
4
|
+
// Postgres DCB log listed in HANDLER_CONFIG from its checkpoint and relays the
|
|
5
|
+
// events, transformed into the {id, meta, event} shape, onto the plugin
|
|
6
|
+
// EventCollector SQS queue — which then fans out to projections, aggregate
|
|
7
|
+
// command topics, and the cross-plugin SNS EventTopic.
|
|
8
|
+
// See docs/plans/aws-postgres-change-feed-bridge.md.
|
|
9
|
+
//
|
|
10
|
+
// HANDLER_CONFIG shape:
|
|
11
|
+
// { "logs": [ { "pgConnection": {host,port,database,username,secretArn},
|
|
12
|
+
// "logName": string, // dcb_event.log_name
|
|
13
|
+
// "subscriber": string, // dcb_subscription checkpoint key
|
|
14
|
+
// "targetQueueUrl": string, // plugin EventCollector SQS URL
|
|
15
|
+
// "partitionTag"?: <derivedPartitionTag> } ] }
|
|
16
|
+
|
|
17
|
+
import { relay } from "@reventlessdev/reventless-aws/src/adapter/Postgres/PgChangeFeedRelay_Runtime.res.mjs";
|
|
18
|
+
import { sendMessage } from "@reventlessdev/reventless-aws/src/util/Util_SQS_Runtime.res.mjs";
|
|
19
|
+
import { makeQueueRef, log } from "./HandlerFactoryHelpers.mjs";
|
|
20
|
+
|
|
21
|
+
// Standard (non-FIFO) EventCollector queue — no message group id needed. The
|
|
22
|
+
// SQS handler parses each body straight back to JSON (Util_SQS_Runtime.parseSqsRecord).
|
|
23
|
+
function makeSendBatch(targetQueueUrl) {
|
|
24
|
+
const queue = makeQueueRef(targetQueueUrl);
|
|
25
|
+
return (jsons) =>
|
|
26
|
+
Promise.all(jsons.map((json) => sendMessage(queue, undefined, JSON.stringify(json)))).then(
|
|
27
|
+
() => {}
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export async function handler(_event, _context) {
|
|
32
|
+
const configStr = process.env["HANDLER_CONFIG"] || '{"logs":[]}';
|
|
33
|
+
const config = JSON.parse(configStr);
|
|
34
|
+
const logs = config.logs || [];
|
|
35
|
+
|
|
36
|
+
await Promise.all(
|
|
37
|
+
logs.map(async (l) => {
|
|
38
|
+
const sendBatch = makeSendBatch(l.targetQueueUrl);
|
|
39
|
+
try {
|
|
40
|
+
const count = await relay(l.pgConnection, l.logName, l.subscriber, l.partitionTag, sendBatch);
|
|
41
|
+
log.debug("relayed " + count + " event(s) for " + l.logName, { comp: "PgChangeFeedRelay" });
|
|
42
|
+
} catch (err) {
|
|
43
|
+
// Log and continue — a failed log this tick is retried next tick from its
|
|
44
|
+
// unchanged checkpoint (at-least-once; projections are idempotent).
|
|
45
|
+
log.warn("relay failed for " + l.logName + ": " + (err?.message ?? String(err)), {
|
|
46
|
+
comp: "PgChangeFeedRelay",
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
})
|
|
50
|
+
);
|
|
51
|
+
return "";
|
|
52
|
+
}
|
|
@@ -78,6 +78,11 @@ let makeFromCodeAsset: (
|
|
|
78
78
|
Lambda's log group (command-handler Lambdas only). Requires a managed log
|
|
79
79
|
group, so it only takes effect when `~logRetentionDays` is also set. */
|
|
80
80
|
~dcbMetrics: bool=?,
|
|
81
|
+
/** Place the Lambda in a VPC (needed to reach RDS/managed Postgres). When set,
|
|
82
|
+
the execution role also gets the EC2 network-interface permissions AWS
|
|
83
|
+
requires for VPC Lambdas. Build it from `PgConnection.{securityGroupId,
|
|
84
|
+
subnetIds}`. */
|
|
85
|
+
~vpcConfig: Pulumi.Input.t<PulumiAws.Lambda.Function.vpcConfig>=?,
|
|
81
86
|
~opts: Pulumi.ComponentResource.options=?,
|
|
82
87
|
) => ReventlessCore.Runtime.environment<parts> = (
|
|
83
88
|
~name,
|
|
@@ -90,6 +95,7 @@ let makeFromCodeAsset: (
|
|
|
90
95
|
~ephemeralStorageMb=?,
|
|
91
96
|
~logRetentionDays=?,
|
|
92
97
|
~dcbMetrics=false,
|
|
98
|
+
~vpcConfig=?,
|
|
93
99
|
~opts=?,
|
|
94
100
|
) => {
|
|
95
101
|
open PulumiAws
|
|
@@ -102,6 +108,37 @@ let makeFromCodeAsset: (
|
|
|
102
108
|
~opts?,
|
|
103
109
|
)
|
|
104
110
|
|
|
111
|
+
// VPC Lambdas must be able to manage ENIs in the target subnets. Attach the
|
|
112
|
+
// standard EC2 network-interface permissions (resource "*", as ENIs have no
|
|
113
|
+
// predictable ARN) whenever the function is VPC-placed.
|
|
114
|
+
vpcConfig->Option.forEach(_ => {
|
|
115
|
+
let _ = PulumiAws.IAM.RolePolicy.make(
|
|
116
|
+
~name=`${name}VpcAccess`,
|
|
117
|
+
~args={
|
|
118
|
+
policy: PolicyDocument.make(
|
|
119
|
+
~id=`${name}VpcAccessPolicy`,
|
|
120
|
+
~statements=[
|
|
121
|
+
{
|
|
122
|
+
sid: "AllowVpcEni",
|
|
123
|
+
effect: Allow,
|
|
124
|
+
actions: Actions([
|
|
125
|
+
"ec2:CreateNetworkInterface",
|
|
126
|
+
"ec2:DescribeNetworkInterfaces",
|
|
127
|
+
"ec2:DeleteNetworkInterface",
|
|
128
|
+
"ec2:AssignPrivateIpAddresses",
|
|
129
|
+
"ec2:UnassignPrivateIpAddresses",
|
|
130
|
+
]),
|
|
131
|
+
resources: Resource("*"),
|
|
132
|
+
},
|
|
133
|
+
],
|
|
134
|
+
)
|
|
135
|
+
->PolicyDocument.toJsonString
|
|
136
|
+
->Pulumi.Input.make,
|
|
137
|
+
role: lambdaRole.id->Pulumi.Output.asInput,
|
|
138
|
+
},
|
|
139
|
+
)
|
|
140
|
+
})
|
|
141
|
+
|
|
105
142
|
// Create additional IAM policies registered by consumers.
|
|
106
143
|
additionalIamPolicies->Array.forEach(({suffix, actions, resourceArn}) => {
|
|
107
144
|
let _ = resourceArn->Pulumi.Output.apply(arn => {
|
|
@@ -160,6 +197,7 @@ let makeFromCodeAsset: (
|
|
|
160
197
|
),
|
|
161
198
|
layers,
|
|
162
199
|
tags,
|
|
200
|
+
vpcConfig: ?vpcConfig,
|
|
163
201
|
environment: ({Lambda.Function.variables: variables}: Lambda.Function.functionEnvironment)
|
|
164
202
|
->Pulumi.Input.make,
|
|
165
203
|
},
|
|
@@ -41,13 +41,30 @@ function make(name, handler, memorySizeOpt, timeoutOpt, opts) {
|
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
function makeFromCodeAsset(name, code, sourceCodeHash, envVarsOpt, memorySizeOpt, timeoutOpt, reservedConcurrency, ephemeralStorageMb, logRetentionDays, dcbMetricsOpt, opts) {
|
|
44
|
+
function makeFromCodeAsset(name, code, sourceCodeHash, envVarsOpt, memorySizeOpt, timeoutOpt, reservedConcurrency, ephemeralStorageMb, logRetentionDays, dcbMetricsOpt, vpcConfig, opts) {
|
|
45
45
|
let envVars = envVarsOpt !== undefined ? envVarsOpt : ({});
|
|
46
46
|
let memorySize = memorySizeOpt !== undefined ? memorySizeOpt : Runtime$ReventlessCore.CommandHandlerDefaults.memorySize;
|
|
47
47
|
let timeout = timeoutOpt !== undefined ? timeoutOpt : Runtime$ReventlessCore.CommandHandlerDefaults.timeout;
|
|
48
48
|
let dcbMetrics = dcbMetricsOpt !== undefined ? dcbMetricsOpt : false;
|
|
49
49
|
let opts$1 = Stdlib_Option.map(opts, Util_Pulumi$ReventlessCore.ComponentResourceOptions.toCustomResourceOptions);
|
|
50
50
|
let lambdaRole = IAM$PulumiAws.Role.makeWithDefaultPolicy(name, Pulumi.output(AWS$ReventlessAws.Lambda.principal), opts$1);
|
|
51
|
+
Stdlib_Option.forEach(vpcConfig, param => {
|
|
52
|
+
new (Aws.iam.RolePolicy)(name + `VpcAccess`, {
|
|
53
|
+
policy: PolicyDocument$PulumiAws.toJsonString(PolicyDocument$PulumiAws.make(undefined, name + `VpcAccessPolicy`, [{
|
|
54
|
+
Sid: "AllowVpcEni",
|
|
55
|
+
Effect: "Allow",
|
|
56
|
+
Action: [
|
|
57
|
+
"ec2:CreateNetworkInterface",
|
|
58
|
+
"ec2:DescribeNetworkInterfaces",
|
|
59
|
+
"ec2:DeleteNetworkInterface",
|
|
60
|
+
"ec2:AssignPrivateIpAddresses",
|
|
61
|
+
"ec2:UnassignPrivateIpAddresses"
|
|
62
|
+
],
|
|
63
|
+
Resource: "*"
|
|
64
|
+
}])),
|
|
65
|
+
role: lambdaRole.id
|
|
66
|
+
});
|
|
67
|
+
});
|
|
51
68
|
additionalIamPolicies.forEach(param => {
|
|
52
69
|
let actions = param.actions;
|
|
53
70
|
let suffix = param.suffix;
|
|
@@ -91,7 +108,8 @@ function makeFromCodeAsset(name, code, sourceCodeHash, envVarsOpt, memorySizeOpt
|
|
|
91
108
|
reservedConcurrentExecutions: Stdlib_Option.map(reservedConcurrency, prim => prim),
|
|
92
109
|
ephemeralStorage: Stdlib_Option.map(ephemeralStorageMb, mb => ({
|
|
93
110
|
size: mb
|
|
94
|
-
}))
|
|
111
|
+
})),
|
|
112
|
+
vpcConfig: vpcConfig
|
|
95
113
|
}, opts$1 !== undefined ? Primitive_option.valFromOption(opts$1) : undefined);
|
|
96
114
|
Stdlib_Option.forEach(logRetentionDays, days => {
|
|
97
115
|
let logGroup = new (Aws.cloudwatch.LogGroup)(name + `LogGroup`, {
|
|
@@ -100,7 +100,7 @@ function finish() {
|
|
|
100
100
|
let envVars = {};
|
|
101
101
|
envVars["HANDLER_CONFIG"] = handlerConfigOutput;
|
|
102
102
|
let match$1 = Util_Bundle$ReventlessAws.buildCodeArchive("@reventlessdev/reventless-aws/src/adapter/Runtime/SideEffectEntryPoint.mjs", packageDirs, undefined);
|
|
103
|
-
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset("AllSideEffectHandlers", match$1.code, match$1.sourceCodeHash, envVars, match[0], match[1], undefined, undefined, undefined, undefined, opts);
|
|
103
|
+
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset("AllSideEffectHandlers", match$1.code, match$1.sourceCodeHash, envVars, match[0], match[1], undefined, undefined, undefined, undefined, undefined, opts);
|
|
104
104
|
let channelSpecs = storedSpecs.map(param => param.channelSpec);
|
|
105
105
|
EventCollectorChannel_DynamoDbStream$ReventlessAws.connect("AllSideEffectHandlers", channelSpecs, runtime, opts);
|
|
106
106
|
} else {
|
|
@@ -43,9 +43,16 @@ let forDcbCommandTopic = (
|
|
|
43
43
|
let channelParts: Util.SQS.channelParts = Obj.magic(channel.parts)
|
|
44
44
|
let queue = channelParts.queue
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
// B2.3c: on a Postgres-backed platform there is no DynamoDB table — DCB events
|
|
47
|
+
// live in `dcb_event` under the canonical log_name `<plugin>DcbEventLog`
|
|
48
|
+
// (= ComponentType.name(_, DcbEventLog), the same string the deploy-time
|
|
49
|
+
// storage + the change-feed relay use). The DcbCommandTopicEntryPoint Postgres
|
|
50
|
+
// branch reads `dcbEventLogTableName` as that log_name.
|
|
51
|
+
let pgSelection = DcbBackend.get()
|
|
52
|
+
let dcbTableName = switch (pgSelection, dcbTableName) {
|
|
53
|
+
| (Some(_), _) => Pulumi.Output.make(pluginName ++ "DcbEventLog")
|
|
54
|
+
| (None, Some(tableName)) => tableName
|
|
55
|
+
| (None, None) => Pulumi.Output.make("NOT_AVAILABLE")
|
|
49
56
|
}
|
|
50
57
|
|
|
51
58
|
// The async DCB CommandTopic is named `<Plugin>DcbAsync` by Dcb_Builder, so the
|
|
@@ -83,11 +90,33 @@ let forDcbCommandTopic = (
|
|
|
83
90
|
})
|
|
84
91
|
->Array.join(",")
|
|
85
92
|
|
|
93
|
+
// B2.3c: on Postgres, add a `pgConnection` object so the entry point selects the
|
|
94
|
+
// Postgres DCB runtime (absent → DynamoDB path, unchanged). Built as a JSON
|
|
95
|
+
// fragment merged into HANDLER_CONFIG below.
|
|
96
|
+
let pgConnectionFragment = switch pgSelection {
|
|
97
|
+
| Some(sel) =>
|
|
98
|
+
sel.connectionConfig->Pulumi.Output.apply(cc => {
|
|
99
|
+
let pgConnectionJson =
|
|
100
|
+
[
|
|
101
|
+
("host", cc.host->JSON.Encode.string),
|
|
102
|
+
("port", cc.port->Int.toFloat->JSON.Encode.float),
|
|
103
|
+
("database", cc.database->JSON.Encode.string),
|
|
104
|
+
("username", cc.username->JSON.Encode.string),
|
|
105
|
+
("secretArn", cc.secretArn->JSON.Encode.string),
|
|
106
|
+
]
|
|
107
|
+
->Dict.fromArray
|
|
108
|
+
->JSON.Encode.object
|
|
109
|
+
->JSON.stringify
|
|
110
|
+
`,"pgConnection":${pgConnectionJson}`
|
|
111
|
+
})
|
|
112
|
+
| None => Pulumi.Output.make("")
|
|
113
|
+
}
|
|
114
|
+
|
|
86
115
|
let handlerConfigJson =
|
|
87
|
-
Pulumi.Output.
|
|
88
|
-
->Pulumi.Output.apply(((table, queueUrl)) => {
|
|
116
|
+
Pulumi.Output.all3((dcbTableName, queue.id, pgConnectionFragment))
|
|
117
|
+
->Pulumi.Output.apply(((table, queueUrl, pgFragment)) => {
|
|
89
118
|
let pluginNameJson = pluginName->JSON.stringifyAny->Option.getOr(`""`)
|
|
90
|
-
`{"dcbEventLogTableName":"${table}","queueUrl":"${queueUrl}","pluginName":${pluginNameJson},"stateChangeSliceModules":[${sliceModulesJson}]}`
|
|
119
|
+
`{"dcbEventLogTableName":"${table}","queueUrl":"${queueUrl}","pluginName":${pluginNameJson},"stateChangeSliceModules":[${sliceModulesJson}]${pgFragment}}`
|
|
91
120
|
})
|
|
92
121
|
envVars->Dict.set("HANDLER_CONFIG", handlerConfigJson->Pulumi.Output.asInput)
|
|
93
122
|
|
|
@@ -120,6 +149,26 @@ let forDcbCommandTopic = (
|
|
|
120
149
|
|
|
121
150
|
cfg.sqsBatchSize->Option.forEach(CommandTopicChannel.SQS.setBatchSize)
|
|
122
151
|
|
|
152
|
+
// B2.3c: Postgres-backed DCB → the command Lambda talks to RDS, so it must land
|
|
153
|
+
// in-VPC on the DB-access security group + private subnets. makeFromCodeAsset
|
|
154
|
+
// adds the EC2-ENI IAM automatically when vpcConfig is present (C1).
|
|
155
|
+
let vpcConfig = switch pgSelection {
|
|
156
|
+
| Some(sel) =>
|
|
157
|
+
Some(
|
|
158
|
+
sel.securityGroupId
|
|
159
|
+
->Pulumi.Output.apply(sgId =>
|
|
160
|
+
(
|
|
161
|
+
{
|
|
162
|
+
PulumiAws.Lambda.Function.subnetIds: sel.subnetIds->Pulumi.Input.make,
|
|
163
|
+
securityGroupIds: [sgId->Pulumi.Input.make]->Pulumi.Input.make,
|
|
164
|
+
}: PulumiAws.Lambda.Function.vpcConfig
|
|
165
|
+
)
|
|
166
|
+
)
|
|
167
|
+
->Pulumi.Output.asInput,
|
|
168
|
+
)
|
|
169
|
+
| None => None
|
|
170
|
+
}
|
|
171
|
+
|
|
123
172
|
let runtime = RuntimeEnvironment_Lambda.makeFromCodeAsset(
|
|
124
173
|
~name,
|
|
125
174
|
~code,
|
|
@@ -130,12 +179,41 @@ let forDcbCommandTopic = (
|
|
|
130
179
|
~reservedConcurrency=?cfg.reservedConcurrency,
|
|
131
180
|
~ephemeralStorageMb=?cfg.ephemeralStorageMb,
|
|
132
181
|
~logRetentionDays=?cfg.logRetentionDays,
|
|
182
|
+
~vpcConfig=?vpcConfig,
|
|
133
183
|
// This is the StateChangeSlice command handler — provision the DCB
|
|
134
184
|
// retry/conflict metric filters (takes effect when logRetentionDays is set).
|
|
135
185
|
~dcbMetrics=true,
|
|
136
186
|
~opts,
|
|
137
187
|
)
|
|
138
188
|
|
|
189
|
+
// B2.3c: grant the Postgres command Lambda read access to the RDS-managed
|
|
190
|
+
// master secret so PgRuntime can resolve the DB password at cold start.
|
|
191
|
+
switch pgSelection {
|
|
192
|
+
| Some(sel) =>
|
|
193
|
+
let _ = sel.connectionConfig->Pulumi.Output.apply(cc => {
|
|
194
|
+
PulumiAws.IAM.RolePolicy.make(
|
|
195
|
+
~name=`${name}-pgSecret`,
|
|
196
|
+
~args={
|
|
197
|
+
policy: PulumiAws.PolicyDocument.make(
|
|
198
|
+
~id=`${name}-pgSecretPolicy`,
|
|
199
|
+
~statements=[
|
|
200
|
+
{
|
|
201
|
+
sid: "AllowGetPgSecret",
|
|
202
|
+
effect: Allow,
|
|
203
|
+
actions: Action("secretsmanager:GetSecretValue"),
|
|
204
|
+
resources: Resource(cc.secretArn),
|
|
205
|
+
},
|
|
206
|
+
],
|
|
207
|
+
)
|
|
208
|
+
->PulumiAws.PolicyDocument.toJsonString
|
|
209
|
+
->Pulumi.Input.make,
|
|
210
|
+
role: runtime.parts.lambdaRole.id->Pulumi.Output.asInput,
|
|
211
|
+
},
|
|
212
|
+
)
|
|
213
|
+
})
|
|
214
|
+
| None => ()
|
|
215
|
+
}
|
|
216
|
+
|
|
139
217
|
// The DCB command topic Lambda is invoked directly by AppSync (Route 1) and
|
|
140
218
|
// needs sqs:SendMessage to publish commands to the FIFO queue for processing.
|
|
141
219
|
// makeWithDefaultPolicy only grants sqs:Receive* (for SQS trigger Route 2).
|
|
@@ -6,6 +6,7 @@ import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
|
6
6
|
import * as Pulumi from "@pulumi/pulumi";
|
|
7
7
|
import * as Logger$ReventlessCore from "@reventlessdev/reventless-core/src/util/Logger.res.mjs";
|
|
8
8
|
import * as Component$ReventlessCore from "@reventlessdev/reventless-core/src/components/Component.res.mjs";
|
|
9
|
+
import * as DcbBackend$ReventlessAws from "../DcbEventLog/DcbBackend.res.mjs";
|
|
9
10
|
import * as PolicyDocument$PulumiAws from "@reventlessdev/rescript-pulumi-aws/src/IAM/PolicyDocument.res.mjs";
|
|
10
11
|
import * as Util_Bundle$ReventlessAws from "../../util/Util_Bundle.res.mjs";
|
|
11
12
|
import * as CommandTopicChannel_SQS$ReventlessAws from "../CommandTopic/CommandTopicChannel_SQS.res.mjs";
|
|
@@ -26,7 +27,10 @@ function forDcbCommandTopic(slicePaths, dcbTableName, pluginName, syncConfig, as
|
|
|
26
27
|
let channel = dcbCommandTopic.channel;
|
|
27
28
|
let channelParts = channel.parts;
|
|
28
29
|
let queue = channelParts.queue;
|
|
29
|
-
let
|
|
30
|
+
let pgSelection = DcbBackend$ReventlessAws.get();
|
|
31
|
+
let dcbTableName$1 = pgSelection !== undefined ? Pulumi.output(pluginName + "DcbEventLog") : (
|
|
32
|
+
dcbTableName !== undefined ? dcbTableName : Pulumi.output("NOT_AVAILABLE")
|
|
33
|
+
);
|
|
30
34
|
let isAsync = baseName.endsWith("Async");
|
|
31
35
|
let name = baseName + "CmdHandler";
|
|
32
36
|
let cfg = isAsync ? asyncConfig : syncConfig;
|
|
@@ -47,12 +51,38 @@ function forDcbCommandTopic(slicePaths, dcbTableName, pluginName, syncConfig, as
|
|
|
47
51
|
let b = Stdlib_Option.getOr(JSON.stringify(param[1]), `""`);
|
|
48
52
|
return `{"spec":` + s + `,"behavior":` + b + `}`;
|
|
49
53
|
}).join(",");
|
|
54
|
+
let pgConnectionFragment = pgSelection !== undefined ? pgSelection.connectionConfig.apply(cc => {
|
|
55
|
+
let pgConnectionJson = JSON.stringify(Object.fromEntries([
|
|
56
|
+
[
|
|
57
|
+
"host",
|
|
58
|
+
cc.host
|
|
59
|
+
],
|
|
60
|
+
[
|
|
61
|
+
"port",
|
|
62
|
+
cc.port
|
|
63
|
+
],
|
|
64
|
+
[
|
|
65
|
+
"database",
|
|
66
|
+
cc.database
|
|
67
|
+
],
|
|
68
|
+
[
|
|
69
|
+
"username",
|
|
70
|
+
cc.username
|
|
71
|
+
],
|
|
72
|
+
[
|
|
73
|
+
"secretArn",
|
|
74
|
+
cc.secretArn
|
|
75
|
+
]
|
|
76
|
+
]));
|
|
77
|
+
return `,"pgConnection":` + pgConnectionJson;
|
|
78
|
+
}) : Pulumi.output("");
|
|
50
79
|
let handlerConfigJson = Pulumi.all([
|
|
51
80
|
dcbTableName$1,
|
|
52
|
-
queue.id
|
|
81
|
+
queue.id,
|
|
82
|
+
pgConnectionFragment
|
|
53
83
|
]).apply(param => {
|
|
54
84
|
let pluginNameJson = Stdlib_Option.getOr(JSON.stringify(pluginName), `""`);
|
|
55
|
-
return `{"dcbEventLogTableName":"` + param[0] + `","queueUrl":"` + param[1] + `","pluginName":` + pluginNameJson + `,"stateChangeSliceModules":[` + sliceModulesJson + `]}`;
|
|
85
|
+
return `{"dcbEventLogTableName":"` + param[0] + `","queueUrl":"` + param[1] + `","pluginName":` + pluginNameJson + `,"stateChangeSliceModules":[` + sliceModulesJson + `]` + param[2] + `}`;
|
|
56
86
|
});
|
|
57
87
|
envVars["HANDLER_CONFIG"] = handlerConfigJson;
|
|
58
88
|
let packageDirs = {};
|
|
@@ -66,7 +96,22 @@ function forDcbCommandTopic(slicePaths, dcbTableName, pluginName, syncConfig, as
|
|
|
66
96
|
packageDirs["@reventlessdev/reventless-core"] = Util_Bundle$ReventlessAws.resolvePackageRoot("@reventlessdev/reventless-core");
|
|
67
97
|
let match = Util_Bundle$ReventlessAws.buildCodeArchive("@reventlessdev/reventless-aws/src/adapter/Runtime/DcbCommandTopicEntryPoint.mjs", packageDirs, undefined);
|
|
68
98
|
Stdlib_Option.forEach(cfg.sqsBatchSize, CommandTopicChannel_SQS$ReventlessAws.setBatchSize);
|
|
69
|
-
let
|
|
99
|
+
let vpcConfig = pgSelection !== undefined ? pgSelection.securityGroupId.apply(sgId => ({
|
|
100
|
+
subnetIds: pgSelection.subnetIds,
|
|
101
|
+
securityGroupIds: [sgId]
|
|
102
|
+
})) : undefined;
|
|
103
|
+
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(name, match.code, match.sourceCodeHash, envVars, cfg.memorySize, cfg.timeout, cfg.reservedConcurrency, cfg.ephemeralStorageMb, cfg.logRetentionDays, true, vpcConfig, opts);
|
|
104
|
+
if (pgSelection !== undefined) {
|
|
105
|
+
pgSelection.connectionConfig.apply(cc => new (Aws.iam.RolePolicy)(name + `-pgSecret`, {
|
|
106
|
+
policy: PolicyDocument$PulumiAws.toJsonString(PolicyDocument$PulumiAws.make(undefined, name + `-pgSecretPolicy`, [{
|
|
107
|
+
Sid: "AllowGetPgSecret",
|
|
108
|
+
Effect: "Allow",
|
|
109
|
+
Action: "secretsmanager:GetSecretValue",
|
|
110
|
+
Resource: cc.secretArn
|
|
111
|
+
}])),
|
|
112
|
+
role: runtime.parts.lambdaRole.id
|
|
113
|
+
}));
|
|
114
|
+
}
|
|
70
115
|
queue.arn.apply(queueArn => new (Aws.iam.RolePolicy)(name + `-sqsSend`, {
|
|
71
116
|
policy: PolicyDocument$PulumiAws.toJsonString(PolicyDocument$PulumiAws.make(undefined, name + `-sqsSendPolicy`, [{
|
|
72
117
|
Sid: "AllowSqsSend",
|
|
@@ -117,7 +117,7 @@ function buildLambda(parent, handlerOutputs, packageDirs, channelSpecs, memorySi
|
|
|
117
117
|
packageDirs["@reventlessdev/reventless-aws"] = Util_Bundle$ReventlessAws.resolvePackageRoot("@reventlessdev/reventless-aws");
|
|
118
118
|
packageDirs["@reventlessdev/reventless-core"] = Util_Bundle$ReventlessAws.resolvePackageRoot("@reventlessdev/reventless-core");
|
|
119
119
|
let match = Util_Bundle$ReventlessAws.buildCodeArchive("@reventlessdev/reventless-aws/src/adapter/Runtime/StateViewSliceEntryPoint.mjs", packageDirs, undefined);
|
|
120
|
-
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset("AllStateViewSlices", match.code, match.sourceCodeHash, envVars, memorySize, timeout, undefined, undefined, undefined, undefined, opts);
|
|
120
|
+
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset("AllStateViewSlices", match.code, match.sourceCodeHash, envVars, memorySize, timeout, undefined, undefined, undefined, undefined, undefined, opts);
|
|
121
121
|
EventCollectorChannel_DynamoDbStream$ReventlessAws.connect("AllStateViewSlices", channelSpecs, runtime, opts);
|
|
122
122
|
}
|
|
123
123
|
|
|
@@ -29,7 +29,7 @@ function forBucketCallback(param, connect, memorySizeOpt, timeoutOpt, name, call
|
|
|
29
29
|
let pkg = Util_Bundle$ReventlessAws.extractPackageName(callbackModulePath);
|
|
30
30
|
packageDirs[pkg] = Util_Bundle$ReventlessAws.resolvePackageRoot(pkg);
|
|
31
31
|
let match = Util_Bundle$ReventlessAws.buildCodeArchive("@reventlessdev/reventless-aws/src/adapter/Runtime/TaskBucketEntryPoint.mjs", packageDirs, undefined);
|
|
32
|
-
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(fullName, match.code, match.sourceCodeHash, envVars, memorySize, timeout, undefined, undefined, undefined, undefined, {
|
|
32
|
+
let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(fullName, match.code, match.sourceCodeHash, envVars, memorySize, timeout, undefined, undefined, undefined, undefined, undefined, {
|
|
33
33
|
parent: resource
|
|
34
34
|
});
|
|
35
35
|
if (schedulerConfig !== undefined) {
|