To be Reviewed By: September 16, 2019

Authors: Dale Emery (demery@pivotal.io)

Status: Draft

Superseded by: N/A

Related: N/A

Problem

Geode currently does not offer a public way to add endpoints to its HTTP server. A developer wishing to serve additional HTTP content must either use internal Geode APIs to add to Geode's server or create a separate server.

For example, Geode collects metrics in a meter registry, but does not publish them. A developer may wish to publish those metrics via HTTP, using a PrometheusMeterRegistry or similar. Geode's existing HTTP server potentially offers a handy way to serve this information.

Solution

Give HttpService a public interface for adding endpoints, and make the instance publicly accessible.

Changes and Additions to Public Interfaces

Rename the current HttpService class as InternalHttpService.

Create a new HttpService public interface with methods like:

  • addHandler(String context, Handler handler) to add a simple Jetty handler at the given context.
  • addContextHandler(contextHandler) to add a Jetty context handler.
  • addWebApplication(String appContext, Path warFilePath) to add a war-based web application.

Let InternalHttpService implement HttpService to add the specified endpoints to its Jetty Server.

Add a getHttpService() method to some public API, returning the InternalHttpService instance as an HttpService. (What is an appropriate candidate for this method?)

Performance Impact

I do not expect adding this API to affect performance in any way. Any user-added endpoint will affect performance, depending on the nature of the endpoint.

Backwards Compatibility and Upgrade Path

I have not assessed whether or how this might affect the rolling upgrade process or backwards compatibility.

Any existing user extensions that depend on the current internal API to add endpoints will break.

Prior Art

Alternative 1: Create a separate server to serve additional content via HTTP. This consumes an additional port, and requires additional work to allocate the port and configure the separate server to use it.

Alternative 2: Use internal APIs to add web applications and handlers. Any user code that does this will break whenever the internal APIs change.

FAQ

Answers to questions you’ve commonly been asked after requesting comments for this proposal.

Errata

What are minor adjustments that had to be made to the proposal since it was approved?

  • No labels

3 Comments

  1. I think this is a good idea. I do have some comments:

    • How will the lifecycle of this service be handled? Should we add a LifecycleHandler  interface as well? At the very least this interface should probably also expose stop() .
    • I don't really like that this interface is coupled to Jetty directly. In the past we've had Tomcat, as the web container, which was replaced by Jetty and in the future we might have something else, so I'd prefer to see the interface be container agnostic.
  2. Since understanding your usage a little better (just needing to add a very simple single endpoint handler) I think you should consider an API that allows you to add a Spring WebApplicationContext instead of the Jetty handler (which I feel are too low level). That way the 'web' code would be a very simple Spring WebMVC app (single Java class) and would be simply bootstrapped as shown in this example: https://bartcode.co.uk/2013/11/using-embedded-jetty-spring-mvc. This approach then also allows any/all of Spring to be applied such as security, automatic marshaling, etc.

    1. I'll look into that. Thanks!