-
Notifications
You must be signed in to change notification settings - Fork 4
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 support for global/project level webhooks #10
Conversation
This PR is ready for first round review. cc @nicksnyder @tsenart @unknwon |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kzh: Would it be possible to remove the whitespace / formatting changes or put them in a separate commit? |
private JsonObject payload; | ||
|
||
private static JsonElement render(Object o) { | ||
String raw = renderer.render(o, new HashMap<>()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Java noob question: What is a HashMap
doing here? Aren't we rendering an Object directly to a JSON String?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The HashMap
is for the options
parameter of the render
function. I think passing in a null
will throw a null pointer exception, so I just pass in an empty one.
I'm not exactly sure how this parameter works either since the docs don't say much 🤔https://docs.atlassian.com/bitbucket-server/javadoc/4.0.2/spi/reference/com/atlassian/bitbucket/json/JsonRenderer.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had a similar question. Can you assign this to a variable so it is clearer?
String raw = renderer.render(o, new HashMap<>()); | |
HashMap<> options = new HashMap<>(); | |
String raw = renderer.render(o, options); |
Do we really have to indirect through a JSON string? There is no method to go directly from a regular object to a JsonElement?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The bitbucket API seems to only expose the render
function which converts bitbucket objects (PullRequest, User, Ref, etc) directly to a JSON string, so there isn't much flexibility.
The other approach would be manually serializing these objects like how events are currently being handled to avoid incurring this redundant operation.
Thanks for the review! I'll ping to request the second round :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leaving this comment here to say: Thorsten was here 😄 I don't know enough about Bitbucket Server's plugin architecture to spot foundational mistakes and my knowledge of Java is superficial, but, that being said, I can't spot obvious mistakes here.
I'm wondering whether we should add some developer/debug experience features such as logging of succesful deliveries, sending a test even for a given PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approving to unblock this PR but left some additional feedback, some of which can definitely be addressed in follow up PRs.
A more general question I have: How has all of this been tested? I think we'd truly benefit from at least one high level system level integration test to make our future lives easier in changing this code.
|
||
@POST | ||
@Consumes(MediaType.APPLICATION_JSON) | ||
public Response put(String raw) throws WebhookException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll need some basic documentation on how to use this API (but that can come in a follow up PR).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question that comes to mind: Are requests authenticated in the same way as the normal Bitbucket Server API?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep!
Authentication
Any authentication that works against Bitbucket will work against the REST API. The preferred authentication methods are HTTP Basic (when using SSL) and OAuth. Other supported methods include: HTTP Cookies and Trusted Applications.
You can find OAuth code samples in several programming languages at bitbucket.org/atlassian_tutorial/atlassian-oauth-examples.
The log-in page uses cookie-based authentication, so if you are using Bitbucket in a browser you can call REST from JavaScript on the page and rely on the authentication that the browser has established.
(https://docs.atlassian.com/bitbucket-server/rest/5.16.0/bitbucket-rest.html)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This talks about the REST API. Does this plugin "extend" the same REST API? Or is it served under a different path? I guess all of these usage questions need to be documented.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I believe the plugin extend the native bitbucket REST API. They're both served under the /rest/
path which requires authentication (else 401s).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to block on my review. I glanced through the code and here are some notes. My biggest ask is to add a lot of documentation.
import java.util.concurrent.ExecutorService; | ||
|
||
@Component | ||
public class Dispatcher { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add class and method doc comments here and everywhere else.
private JsonObject payload; | ||
|
||
private static JsonElement render(Object o) { | ||
String raw = renderer.render(o, new HashMap<>()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had a similar question. Can you assign this to a variable so it is clearer?
String raw = renderer.render(o, new HashMap<>()); | |
HashMap<> options = new HashMap<>(); | |
String raw = renderer.render(o, options); |
Do we really have to indirect through a JSON string? There is no method to go directly from a regular object to a JsonElement?
Co-Authored-By: Nick Snyder <[email protected]>
@kzh: Can you please summarise the current state of this PR? What's left to do and what's your expected timeline? |
@christinaforney: By the way, since this plugin isn't tied to our release cycle, there isn't any hard requirement for us to ship this at the same time as 3.10. We have to implement support in Sourcegraph for receiving and processing these webhooks in 3.11 anyways, so no rush necessary here. |
Great. Will that follow up PR also include Java docs that @nicksnyder asked for? If so, let's merge this! |
@kzh: I'd share that screenshot in our #progress channel! Thank you for working on this 🙇 |
This PR adds support for global and project scoped webhooks.
REST Endpoints:
<bitbucket url>/rest/sourcegraph-admin/1.0/webhook
Listing:
$ curl <bitbucket url>/rest/sourcegraph-admin/1.0/webhook
Creating:
$ curl <bitbucket url>/rest/sourcegraph-admin/1.0/webhook -d 'scope=<scope>&identifier=<identifier>&events=<events>&external=<external>'
global
|project
|repository
Deleting:
$ curl -X DELETE <bitbucket url>/rest/sourcegraph-admin/1.0/webhook -d 'id=<id>'
$ curl -X DELETE <bitbucket url>/rest/sourcegraph-admin/1.0/webhook -d 'name=<name>'
For authorization, include these flags:
-u admin:admin -H "X-Atlassian-Token: no-check"
.The event payload aims to follow these JSON schemas:
Todo:
/webhooks
) for CRUDing WebhooksPullRequestEvent
This is a part of sourcegraph/sourcegraph#6091.