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

Add offline support to the API to make parsing events easier #306

Merged
merged 10 commits into from
Nov 17, 2016

Conversation

stephenc
Copy link
Contributor

@stephenc stephenc commented Nov 8, 2016

  • When we receive events from a webhook, it is non-trivial to determine which GitHub instance the event came from
    or for that matter even if the event actually came from GitHub or GitHub Enterprise.
  • In order to ensure that the logic for parsing events does not get replicated in clients, we need to be
    able to call GitHub.parseEventPayload(Reader,Class) without knowing which GitHub the event originates from
    and without the resulting objects triggering API calls back to a GitHub
  • Thus we add GitHub.offline() to provide an off-line connection
  • Thus we modify some of the object classes to return best-effort objects when off-line
  • Add support for more of the event types into GHEventPayload
  • Add tests of the event payload and accessing critical fields when using GitHub.offline()

@reviewbybees

- When we receive events from a webhook, it is non-trivial to determine which GitHub instance the event came from
  or for that matter even if the event actually came from GitHub or GitHub Enterprise.
- In order to ensure that the logic for parsing events does not get replicated in clients, we need to be
  able to call GitHub.parseEventPayload(Reader,Class) without knowing which GitHub the event originates from
  and without the resulting objects triggering API calls back to a GitHub
- Thus we add GitHub.offline() to provide an off-line connection
- Thus we modify some of the object classes to return best-effort objects when off-line
- Add support for more of the event types into GHEventPayload
- Add tests of the event payload and accessing critical fields when using GitHub.offline()
@ghost
Copy link

ghost commented Nov 8, 2016

This pull request originates from a CloudBees employee. At CloudBees, we require that all pull requests be reviewed by other CloudBees employees before we seek to have the change accepted. If you want to learn more about our process please see this explanation.

Copy link
Contributor

@jglick jglick left a comment

Choose a reason for hiding this comment

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

🐝 (assuming a downstream PR is in the making)

@@ -35,7 +35,7 @@
GHIssue owner;

private String body, gravatar_id;
private GHUser user;
private GHUser user; // not fully populated. beware.
Copy link
Contributor

Choose a reason for hiding this comment

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

Seems like this sort of comment would better be placed in the Javadoc of the getter.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yep... just copying existing code style

@@ -216,13 +216,39 @@ public static GitHub connectToEnterpriseAnonymously(String apiUrl) throws IOExce
}

/**
* An off-line only {@link GitHub} useful for parsing event notification from an unknown source.
Copy link
Contributor

Choose a reason for hiding this comment

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

offline-only

return IOUtils.toByteArray(input);
} finally {
IOUtils.closeQuietly(input);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

try (InputStream input = asInputStream()) {
    return IOUtils.toByteArray(input);
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Java 5 (yes WAT!)

}

public Reader asReader() throws FileNotFoundException {
return new InputStreamReader(asInputStream(), Charset.defaultCharset());
Copy link
Contributor

Choose a reason for hiding this comment

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

Since this is being used for JSON, I would think UTF-8 would be more appropriate.

"avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3",
"gravatar_id": "",
"url": "https://api.github.com/users/baxterthehacker",
"html_url": "https://github.com/baxterthehacker",
Copy link
Contributor

Choose a reason for hiding this comment

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

Who are you really @baxterthehacker? :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

These are the samples from github's api docs

/**
* @author Stephen Connolly
*/
public class PayloadRule implements TestRule {
Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a kohsuke project not a jenkins project (would be nice if it was something we could release without KK)

Copy link
Contributor

@jglick jglick left a comment

Choose a reason for hiding this comment

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

re:bee:

*/
@SuppressFBWarnings(value = {"UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR", "NP_UNWRITTEN_FIELD" },
justification = "Constructed by JSON deserialization")
public static class CommitComment extends GHEventPayload {
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe its better to place this classes in separate files?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it would have been better if the design was originally that way... but needs to be in same package due to current API design (FTR I would not have designed this API this way as it is very tricky to unpick the stuff that requires a connection from the stuff that doesn't... but we are where we are)

public void pull_request() throws Exception {
GHEventPayload.PullRequest event =
GitHub.offline().parseEventPayload(payload.asReader(), GHEventPayload.PullRequest.class);
assertThat(event.getAction(), is("opened"));
Copy link
Contributor

Choose a reason for hiding this comment

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

you can create expected object and use haveSameProperties matcher

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That runs the risk of following requests for the partial objects that are not available from the event objects. safer to just test the paths

Copy link
Collaborator

@oleg-nenashev oleg-nenashev left a comment

Choose a reason for hiding this comment

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

👍 Should be a nice improvement. And 🐝

* Gets the sender or {@code null} if accessed via the events API.
* @return the sender or {@code null} if accessed via the events API.
*/
public GHUser getSender() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

CheckForNull. Nobody reads Javadoc

Copy link
Collaborator

Choose a reason for hiding this comment

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

But generally applies to all deserialized fields :(

@@ -147,6 +489,11 @@ public String getBefore() {
return before;
}

@JsonSetter // alias
private void setAfter(String after) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe it worth to add getter as well. Just to avoid confusing people

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's private just using this as an alias field name... the documented sample event payload says "after" the documented event says "head" and my tests say "head" but the alias is here as a "just in case"

@kohsuke kohsuke merged commit d1378a0 into hub4j:master Nov 17, 2016
@stephenc stephenc deleted the offline-support branch November 1, 2017 15:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants