Skip to content

Commit 4239f18

Browse files
Update firebasedatabase event conversion logic (#107)
* Update firebasedatabase event conversion logic Recently the format of Firebase RTDB event was updated to include location information in the source. When upcasting, this can be derived from the domain field of a legacy event as described here: https://github.com/GoogleCloudPlatform/functions-framework-conformance/blob/master/docs/mapping.md#firebase-rtdb-events-tentative * fix lint errors * review feedback * added test for firebase-dbdelete2.json
1 parent 6686ce3 commit 4239f18

File tree

6 files changed

+50
-8
lines changed

6 files changed

+50
-8
lines changed

.github/workflows/conformance.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ jobs:
2727
- name: Bundle install
2828
run: 'bundle install'
2929
- name: Run HTTP conformance tests
30-
uses: GoogleCloudPlatform/functions-framework-conformance/[email protected].9
30+
uses: GoogleCloudPlatform/functions-framework-conformance/[email protected].12
3131
with:
3232
functionType: 'http'
3333
useBuildpacks: false
3434
cmd: "'bundle exec functions-framework-ruby --source test/conformance/app.rb --target http_func --signature-type http'"
3535
- name: Run CloudEvent conformance tests
36-
uses: GoogleCloudPlatform/functions-framework-conformance/[email protected].11
36+
uses: GoogleCloudPlatform/functions-framework-conformance/[email protected].12
3737
with:
3838
functionType: 'cloudevent'
3939
useBuildpacks: false

lib/functions_framework/legacy_event_converter.rb

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,11 @@ def normalized_context input
8484
id = normalized_context_field input, "eventId"
8585
timestamp = normalized_context_field input, "timestamp"
8686
type = normalized_context_field input, "eventType"
87+
domain = normalized_context_field input, "domain"
8788
service, resource = analyze_resource normalized_context_field input, "resource"
8889
service ||= service_from_type type
8990
return nil unless id && timestamp && type && service && resource
90-
{ id: id, timestamp: timestamp, type: type, service: service, resource: resource }
91+
{ id: id, timestamp: timestamp, type: type, service: service, resource: resource, domain: domain }
9192
end
9293

9394
def normalized_context_field input, field
@@ -114,7 +115,7 @@ def service_from_type type
114115
end
115116

116117
def construct_cloud_event context, data
117-
source, subject = convert_source context[:service], context[:resource]
118+
source, subject = convert_source context[:service], context[:resource], context[:domain]
118119
type = LEGACY_TYPE_TO_CE_TYPE[context[:type]]
119120
return nil unless type && source
120121
ce_data, data_subject = convert_data context, data
@@ -129,12 +130,24 @@ def construct_cloud_event context, data
129130
time: context[:timestamp]
130131
end
131132

132-
def convert_source service, resource
133+
def convert_source service, resource, domain
133134
return ["//#{service}/#{resource}", nil] unless CE_SERVICE_TO_RESOURCE_RE.key? service
134135

135136
match = CE_SERVICE_TO_RESOURCE_RE[service].match resource
136137
return [nil, nil] unless match
137-
["//#{service}/#{match[1]}", match[2]]
138+
139+
if service == "firebasedatabase.googleapis.com"
140+
return [nil, nil] if domain.nil?
141+
location = "us-central1"
142+
if domain != "firebaseio.com"
143+
location_match = domain.match(/^([\w-]+)\.firebasedatabase\.app$/)
144+
return [nil, nil] unless location_match
145+
location = location_match[1]
146+
end
147+
["//#{service}/projects/_/locations/#{location}/#{match[1]}", match[2]]
148+
else
149+
["//#{service}/#{match[1]}", match[2]]
150+
end
138151
end
139152

140153
def convert_data context, data
@@ -192,7 +205,7 @@ def convert_data context, data
192205

193206
CE_SERVICE_TO_RESOURCE_RE = {
194207
"firebase.googleapis.com" => %r{^(projects/[^/]+)/(events/[^/]+)$},
195-
"firebasedatabase.googleapis.com" => %r{^(projects/_/instances/[^/]+)/(refs/.+)$},
208+
"firebasedatabase.googleapis.com" => %r{^projects/_/(instances/[^/]+)/(refs/.+)$},
196209
"firestore.googleapis.com" => %r{^(projects/[^/]+/databases/\(default\))/(documents/.+)$},
197210
"storage.googleapis.com" => %r{^(projects/[^/]+/buckets/[^/]+)/([^#]+)(?:#.*)?$}
198211
}.freeze

test/legacy_events_data/firebase-db1.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"auth": {
77
"admin": true
88
},
9+
"domain":"firebaseio.com",
910
"data": {
1011
"data": null,
1112
"delta": {

test/legacy_events_data/firebase-dbdelete1.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"auth": {
77
"admin": true
88
},
9+
"domain":"europe-west1.firebasedatabase.app",
910
"data": {
1011
"data": {
1112
"grandchild": "other changed"

test/legacy_events_data/firebase-dbdelete2.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"auth": {
77
"admin": true
88
},
9+
"domain":"firebaseio.com",
910
"data": {
1011
"data": 10,
1112
"delta": null

test/test_legacy_event_converter.rb

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,10 +186,36 @@ def load_legacy_event filename, url_path: nil, encoding: "utf-8"
186186
event = load_legacy_event "firebase-db1.json"
187187
assert_equal "1.0", event.spec_version
188188
assert_equal "/SnHth9OSlzK1Puj85kk4tDbF90=", event.id
189-
assert_equal "//firebasedatabase.googleapis.com/projects/_/instances/my-project-id", event.source.to_s
189+
assert_equal \
190+
"//firebasedatabase.googleapis.com/projects/_/locations/us-central1/instances/my-project-id",
191+
event.source.to_s
190192
assert_equal "google.firebase.database.document.v1.written", event.type
191193
assert_equal "refs/gcf-test/xyz", event.subject
192194
assert_equal "2020-05-21T11:15:34+00:00", event.time.rfc3339
193195
assert_equal "other", event.data["delta"]["grandchild"]
194196
end
197+
198+
it "converts firebase-dbdelete1.json" do
199+
event = load_legacy_event "firebase-dbdelete1.json"
200+
assert_equal "1.0", event.spec_version
201+
assert_equal "oIcVXHEMZfhQMNs/yD4nwpuKE0s=", event.id
202+
assert_equal \
203+
"//firebasedatabase.googleapis.com/projects/_/locations/europe-west1/instances/my-project-id",
204+
event.source.to_s
205+
assert_equal "google.firebase.database.document.v1.deleted", event.type
206+
assert_equal "refs/gcf-test/xyz", event.subject
207+
assert_equal "2020-05-21T11:53:45+00:00", event.time.rfc3339
208+
end
209+
210+
it "converts firebase-dbdelete2.json" do
211+
event = load_legacy_event "firebase-dbdelete2.json"
212+
assert_equal "1.0", event.spec_version
213+
assert_equal "KVLKeFKjFP2jepddr+EPGC0ZQ20=", event.id
214+
assert_equal \
215+
"//firebasedatabase.googleapis.com/projects/_/locations/us-central1/instances/my-project-id",
216+
event.source.to_s
217+
assert_equal "google.firebase.database.document.v1.deleted", event.type
218+
assert_equal "refs/gcf-test/abc", event.subject
219+
assert_equal "2020-05-21T11:56:12+00:00", event.time.rfc3339
220+
end
195221
end

0 commit comments

Comments
 (0)