Skip to content

Conversation

grant
Copy link
Contributor

@grant grant commented Mar 23, 2021

Refactors event conversion and implements partial event conversion.

  • Enables linting on full source code
  • Adds many tests to invoker
  • Implements CE downcasting
  • Refactors CloudEvent conversion
  • No external changes to existing functions interface

Test Output

CloudEvents: Utility methods
    ✓ should correctly eval if a CloudEvent is "binary"
    ✓ should correctly eval if a CloudEvent is "structured"
    ✓ should convert requests to a structured CE
    ✓ should get a binary CE from a request

  Invoker: CE -> CE
    ✓ should receive cloudevent from CloudEvents v1.0 structured content mode (39ms)
    ✓ should receive cloudevent from CloudEvents v1.0 binary content mode
    ✓ should receive cloudevent from CloudEvents v1.0 binary content mode with only required fields

  EventConverter: CE -> Legacy
    ✓ should downcast events

  Invoker: CE -> Legacy
    ✓ should receive data and context from CloudEvents v1.0 structured content mode

  EventConverter: Legacy -> CE
    ✓ should upcast Pub/Sub events
    ✓ should upcast legacy Pub/Sub events
    ✓ should upcast Firebase Auth events

  Invoker: HTTP
    ✓ should return the correct HTTP status and call count: empty path
    ✓ should return the correct HTTP status and call count: simple path
    ✓ should return the correct HTTP status and call count: with favicon.ico
    ✓ should return the correct HTTP status and call count: with robots.txt

  Invoker: Legacy Event -> Legacy Event
    ✓ should receive data and context from GCF event
    ✓ should receive data and context from GCF legacy event
    ✓ should receive data and context from GCF event with resource JSON

  Function loader
    ✓ should load function without "main" in package.json
    ✓ should load function with "main" in package.json


  21 passing (107ms)

(Reference) Previous Test Output

request to HTTP function
    ✓ should return transformed body: empty path (43ms)
    ✓ should return transformed body: simple path
    ✓ should return transformed body: with favicon.ico
    ✓ should return transformed body: with robots.txt

  GCF event request to event function
    ✓ should receive data and context from GCF event
    ✓ should receive data and context from GCF legacy event
    ✓ should receive data and context from GCF event with resource JSON

  CloudEvents request to event function
    ✓ should receive data and context from CloudEvents v1.0 structured content mode
    ✓ should receive data and context from CloudEvents v1.0 binary content mode

  CloudEvents request to cloudevent function
    ✓ should receive data and context from CloudEvents v1.0 structured content mode
    ✓ should receive data and context from CloudEvents v1.0 binary content mode

  loading function
    ✓ should load function without "main" in package.json
    ✓ should load function with "main" in package.json


  13 passing (99ms)

grant added 3 commits March 23, 2021 12:05
Signed-off-by: Grant Timmerman <timmerman+devrel@google.com>
Signed-off-by: Grant Timmerman <timmerman+devrel@google.com>
Signed-off-by: Grant Timmerman <timmerman+devrel@google.com>
@grant grant self-assigned this Mar 23, 2021
@google-cla google-cla bot added the cla: yes label Mar 23, 2021
grant added 6 commits March 31, 2021 12:20
Signed-off-by: Grant Timmerman <timmerman+devrel@google.com>
Signed-off-by: Grant Timmerman <timmerman+devrel@google.com>
Signed-off-by: Grant Timmerman <timmerman+devrel@google.com>
Signed-off-by: Grant Timmerman <timmerman+devrel@google.com>
Signed-off-by: Grant Timmerman <timmerman+devrel@google.com>
Signed-off-by: Grant Timmerman <timmerman+devrel@google.com>
@grant grant changed the title ci: conformance action 2 feat: implement CloudEvent down Conversion & Adds Tests Apr 6, 2021
@grant grant requested a review from mtraver April 6, 2021 23:11
@grant grant marked this pull request as ready for review April 6, 2021 23:11
@grant
Copy link
Contributor Author

grant commented Apr 6, 2021

Should be ready to review @mtraver. Pardon the large PR.
We can move parts of the changes to a separate PR is needed.

@grant grant requested a review from matthewrobertson April 8, 2021 18:04
with:
functionType: 'http'
useBuildpacks: false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like this should be false by default, no? Any reason to add it in this PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it's not needed. We can remove.

package.json Outdated
"check": "gts check",
"clean": "gts clean",
"compile": "tsc -p .",
"watch": "tsc -p . -w",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe DRY this up with:

"watch": "npm run compile -- --watch",

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

return ce;
} else {
// Structured event. Just return the event, which is stored in the HTTP body.
return req.body;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how does this pass the typechecker right now?

* @return True if the request is a CloudEvents event in structured content mode,
* false otherwise.
*/
export function isStructuredCloudEvent(req: express.Request): boolean {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there an opportunity to use a type predicate here? Something like:

interface StructuredCloudEventRequest extends express.Request {
  body: CloudEventsContext;
}
export function isStructuredCloudEvent(req: express.Request) req is StructuredCloudEventRequest

@@ -0,0 +1,113 @@
// Copyright 2021 Google LLC
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as above: test/integration/legacyEvents.ts?

// TEST_CLOUDEVENT_STRUCTURED,
// } from './data/testHTTPData';

describe('EventConverter: CE -> Legacy', () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as below, if you programatically skip, you don't have comment out the imports:

describe.skip('EventConverter: CE -> Legacy', () => {

Comment on lines +78 to +92
const ce: CloudEventsContext = {
specversion: req.header('ce-specversion'),
type: req.header('ce-type'),
source: req.header('ce-source'),
subject: req.header('ce-subject'),
id: req.header('ce-id'),
time: req.header('ce-time'),
datacontenttype: req.header('ce-datacontenttype'),
data: req.body,
};
// Remove undefined keys from CE object
Object.keys(ce).forEach((key: string) =>
ce[key] === undefined ? delete ce[key] : {}
);
return ce;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might write this a bit differently. Rather than going through and deleting undefined keys, just don't set them in the first place:

const ce: CloudEventsContext = {
  data: req.body,
};
[
  'specversion',
  'type',
  'source',
  'subject',
  'id',
  'time',
  'datacontenttype',
].forEach((key) => {
  if (req.header(`ce-${key}`) !== undefined) {
    ce[key] = req.header(`ce-${key}`);
  }
}

even better would be to move that array to a constant somewhere

/**
* Returns a CloudEvents context from the given CloudEvents request. Context
* attributes are retrieved from request headers.
*
* @param req Express request object.
* @return CloudEvents context.
*/
export function getBinaryCloudEventContext(
export function getStructuredCloudEventContext(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am a bit confused about how this function is different from convertRequestToStructuredCE

Comment on lines +209 to +211
// Set data and context normally
data = req.body.data;
context = req.body.context;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like these variables are already initialized to exactly these values on line 186/187. Can we just remove the else block here or remove the initial values above?

Comment on lines +194 to +197
} else {
// If a really legacy event, convert it to a normal event.
// See the tests for more details.
if (!context) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: flatten to } else if (!context) {

Copy link
Member

@matthewrobertson matthewrobertson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Formally requesting changes because I am sure if you saw my review.

@grant
Copy link
Contributor Author

grant commented Apr 19, 2021

Thanks. I'll have to apply the comments and likely break this PR into some smaller PRs.

Signed-off-by: Grant Timmerman <timmerman+devrel@google.com>
@grant
Copy link
Contributor Author

grant commented Apr 21, 2021

I've pulled out a few changes into separate PRs. I think it will make things cleaner and safer:

Signed-off-by: Grant Timmerman <timmerman+devrel@google.com>
@grant grant force-pushed the grant_ci_update_2 branch from acb2053 to b378ccf Compare April 21, 2021 18:01
grant added 2 commits April 21, 2021 13:03
Signed-off-by: Grant Timmerman <timmerman+devrel@google.com>
Signed-off-by: Grant Timmerman <timmerman+devrel@google.com>
@grant
Copy link
Contributor Author

grant commented May 6, 2021

Going to close this PR. Other PRs will be able to complete the conversions. Feel free to ping me if there are questions.

@grant grant closed this May 6, 2021
@grant grant deleted the grant_ci_update_2 branch May 6, 2021 19:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants