mesosphere/marathon — pull request #159 by everpeace (2014-02-23 05:19:42+00:00)
Title: Added event subscriptions endpoint

Ref #147

I added below endpoint

* endpoint path => `/v2/event_subscriptions`
* supported methods =>
* `POST` with `?callback_url`
returns whether registration was succeeded or not.
And, this api call will be also notified subscribers (including callee).
* `DELETE` with `?callback_url`
returns whether un-registration was succeeded or not.
And, this api call will be also notified subscribers (excluding callee).
* `GET`
returns list of subscribers.
And, this api call will NOT be notified. ( I know that [Event-Bus](https://github.com/mesosphere/marathon/wiki/Event-Bus) says that _"Marathon has an internal event bus that captures all API requests and scaling events."_)

In this modification, I made some changes to Marathon's core components below:

* `message EventSubscribers` was added to `marathon.proto`. (so, `Protos.java` was also regenerated. I compile `marathon.proto` with protobuf 2.4.1 and mesos 0.15.0, as specified in `pom.xml`)
* `MarathonStore` was slightly modified:
* change `prefix` to be customizable.
* `modify(key)( ( () => S ) => S )` was instroduced.
* () =>S returns deserialized S value, which enables to avoid unnecessary deserialization overhead.
* consequently, `store(key,value)` was implemented as `modify(key)(_=>newvalue)` at `PersistenceStore`

Also, I would like to note that I used [optional injection](https://code.google.com/p/google-guice/wiki/Injections#Optional_Injections) on [`EventSubscriptionsResource`](https://github.com/everpeace/marathon/blob/add-subscription-endpoint/src/main/scala/mesosphere/marathon/api/v2/EventSubscriptionsResource.scala#L22-23) for realizing conditional injection.

Api resources must be always published because http requests to marathon instance will be forwarded to the leader as you mentioned even when `--event_subscriber` was NOT specified at startup.

However, `EventSubscriptionResource` depends on ` HttpCallbackSubscriptionService`. And, [dependencies of `HttpCallbackSubscriptionService`](https://github.com/everpeace/marathon/blob/add-subscription-endpoint/src/main/scala/mesosphere/marathon/event/http/HttpCallbackSubscriptionService.scala#L11-L13) are initialized only when `--event_subscriber http_callback` is specified at startup. Therefore, if the normal `@Inject` annotation was used, Guice raises an initialization exception during instantiating `HttpCallbackSubscriptionService`. Optional injection can avoid this.