Skip to content

Commit

Permalink
Merge 425b373 into 4f4acf4
Browse files Browse the repository at this point in the history
  • Loading branch information
jmwski committed May 31, 2019
2 parents 4f4acf4 + 425b373 commit 73ca02b
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 10 deletions.
1 change: 1 addition & 0 deletions src/emulator/constants.ts
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";

static getDefaultHost(emulator: Emulators): string {
return DEFAULT_HOST;
Expand Down
25 changes: 15 additions & 10 deletions src/emulator/controller.ts
Expand Up @@ -154,17 +154,22 @@ export async function startAll(options: any): Promise<void> {

if (targets.indexOf(Emulators.DATABASE) > -1) {
const databaseAddr = Constants.getAddress(Emulators.DATABASE, options);
const databaseEmulator = new DatabaseEmulator({
host: databaseAddr.host,
port: databaseAddr.port,
});
let databaseEmulator;
if (targets.indexOf(Emulators.FUNCTIONS) > -1) {
const functionsAddr = Constants.getAddress(Emulators.FUNCTIONS, options);
databaseEmulator = new DatabaseEmulator({
host: databaseAddr.host,
port: databaseAddr.port,
functions_emulator_host: functionsAddr.host,
functions_emulator_port: functionsAddr.port,
});
} else {
databaseEmulator = new DatabaseEmulator({
host: databaseAddr.host,
port: databaseAddr.port,
});
}
await startEmulator(databaseEmulator);

// TODO: When the database emulator is integrated with the Functions
// emulator, we will need to pass the port in and remove this warning
utils.logWarning(
`Note: the database emulator is not currently integrated with the functions emulator.`
);
}

if (targets.indexOf(Emulators.HOSTING) > -1) {
Expand Down
2 changes: 2 additions & 0 deletions src/emulator/databaseEmulator.ts
Expand Up @@ -5,6 +5,8 @@ import { Constants } from "./constants";
interface DatabaseEmulatorArgs {
port?: number;
host?: string;
functions_emulator_port?: number;
functions_emulator_host?: string;
}

export class DatabaseEmulator implements EmulatorInstance {
Expand Down
79 changes: 79 additions & 0 deletions src/emulator/functionsEmulator.ts
Expand Up @@ -32,6 +32,14 @@ import { EmulatorLogger, Verbosity } from "./emulatorLogger";

const EVENT_INVOKE = "functions:invoke";

/*
* The Realtime Database emulator expects the `path` field in its trigger
* definition to be relative to the database root. This regex is used to extract
* that path from the `resource` member in the trigger definition used by the
* functions emulator.
*/
const DATABASE_PATH_PATTERN = new RegExp("^projects/[^/]+/instances/[^/]+/refs(/.*)$");

export interface FunctionsEmulatorArgs {
port?: number;
host?: string;
Expand Down Expand Up @@ -490,6 +498,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 +525,74 @@ 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();
}

const result: string[] | null = DATABASE_PATH_PATTERN.exec(definition.eventTrigger.resource);
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/${definition.name}`,
},
]);

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

0 comments on commit 73ca02b

Please sign in to comment.