Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modify functions emulator to invoke RTDB emulator triggers #1347

Merged
merged 21 commits into from
Jun 5, 2019
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
edb03ac
Add RTDB emulator support to the functions emulator
jmwski May 28, 2019
ae0ffe4
Add auth header to function trigger setup request
jmwski May 29, 2019
783d764
Fix lint errors
jmwski May 30, 2019
17edb2d
Use regex to extract database-root-relative paths for trigger creation
jmwski May 30, 2019
04cbfa3
Merge branch 'master' into wyszynski/rtdb-emulator-functions
jmwski May 30, 2019
fceb7f2
Make path extractor regex a constant, enforce non-empty instance and …
jmwski May 30, 2019
75375b5
Merge branch 'master' into wyszynski/rtdb-emulator-functions
jmwski May 30, 2019
0485229
Pass functions emulator arguments to database emulator when present
jmwski May 30, 2019
cad56b2
Merge branch 'wyszynski/rtdb-emulator-functions' of https://github.co…
jmwski May 30, 2019
324f073
Add trigger definition name to invocation payload topicName
jmwski May 31, 2019
425b373
Use snake-case in database emulator args
jmwski May 31, 2019
2646aa1
Add RTDB emulator support to the functions emulator
jmwski May 28, 2019
70b443c
Add auth header to function trigger setup request
jmwski May 29, 2019
4ca8b4d
Fix lint errors
jmwski May 30, 2019
a830f41
Use regex to extract database-root-relative paths for trigger creation
jmwski May 30, 2019
2cdc215
Make path extractor regex a constant, enforce non-empty instance and …
jmwski May 30, 2019
2cbd0eb
Pass functions emulator arguments to database emulator when present
jmwski May 30, 2019
cba83e2
Add trigger definition name to invocation payload topicName
jmwski May 31, 2019
db05600
Use snake-case in database emulator args
jmwski May 31, 2019
b3ae92e
Merge branch 'wyszynski/rtdb-emulator-functions' of https://github.co…
jmwski Jun 4, 2019
f4010dd
Release database emulator v4.0.0
jmwski Jun 4, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions src/emulator/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const DEFAULT_HOST = "localhost";

export class Constants {
static SERVICE_FIRESTORE = "firestore.googleapis.com";
static SERVICE_REALTIME_DATABASE = "firebaseio.com";
jmwski marked this conversation as resolved.
Show resolved Hide resolved

static getDefaultHost(emulator: Emulators): string {
return DEFAULT_HOST;
Expand Down
76 changes: 76 additions & 0 deletions src/emulator/functionsEmulator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,9 @@ You can probably fix this by running "npm install ${
case Constants.SERVICE_FIRESTORE:
await this.addFirestoreTrigger(this.projectId, definition);
break;
case Constants.SERVICE_REALTIME_DATABASE:
await this.addRealtimeDatabaseTrigger(this.projectId, definition);
break;
default:
EmulatorLogger.log("DEBUG", `Unsupported trigger: ${JSON.stringify(definition)}`);
EmulatorLogger.log(
Expand All @@ -514,6 +517,79 @@ You can probably fix this by running "npm install ${
return loadTriggers();
}

addRealtimeDatabaseTrigger(
projectId: string,
definition: EmulatedTriggerDefinition
): Promise<any> {
const databasePort = EmulatorRegistry.getPort(Emulators.DATABASE);
if (!databasePort) {
EmulatorLogger.log(
"INFO",
`Ignoring trigger "${
definition.name
}" because the Realtime Database emulator is not running.`
);
return Promise.resolve();
}
if (definition.eventTrigger === undefined) {
EmulatorLogger.log(
"WARN",
`Event trigger "${definition.name}" has undefined "eventTrigger" member`
);
return Promise.reject();
}
/*
* The Realtime Database emulator expects the `path` field in its trigger
* definition to be relative to the database root.
*/
const pathPattern = new RegExp("^projects/[^/]*/instances/[^/]*/refs(/.*)$");
jmwski marked this conversation as resolved.
Show resolved Hide resolved
const result: string[] | null = pathPattern.exec(definition.eventTrigger.resource);
yuchenshi marked this conversation as resolved.
Show resolved Hide resolved

if (result === null || result.length !== 2) {
EmulatorLogger.log(
"WARN",
`Event trigger "${definition.name}" has malformed "resource" member. ` +
`${definition.eventTrigger.resource}`
);
return Promise.reject();
}

const bundle = JSON.stringify([
{
name: `projects/${projectId}/locations/_/functions/${definition.name}`,
path: result[1], // path stored in the first capture group
event: definition.eventTrigger.eventType,
topic: `projects/${projectId}/topics/_`,
},
]);

EmulatorLogger.logLabeled(
"BULLET",
"functions",
`Setting up Realtime Database trigger "${definition.name}"`
);
logger.debug(`addDatabaseTrigger`, JSON.stringify(bundle));
return new Promise((resolve, reject) => {
request.put(
`http://localhost:${databasePort}/.settings/functionTriggers.json`,
{
auth: {
bearer: "owner",
},
body: bundle,
},
(err, res, body) => {
if (err) {
EmulatorLogger.log("WARN", "Error adding trigger: " + err);
reject();
return;
}
resolve();
}
);
});
}

addFirestoreTrigger(projectId: string, definition: EmulatedTriggerDefinition): Promise<any> {
const firestorePort = EmulatorRegistry.getPort(Emulators.FIRESTORE);
if (!firestorePort) {
Expand Down