@PublicApi

Package com.yahoo.jdisc.service

Provides classes and interfaces for implementing a ClientProvider or a ServerProvider.

ServerProvider

All Requests that are processed in a jDISC application are created by ServerProviders. These are components created by the Application, and they are the parts of jDISC that accept incoming connections. The ServerProvider creates and dispatches Request instances to the CurrentContainer. No Request is ever dispatched to a ServerProvider, so a ServerProvider is considered part of the Application and not part of a Container (as opposed to RequestHandlers and ClientProviders). To create a Request the ServerProvider first composes a URI on the form <scheme>://localhost[:<port>]/<path> that matches the content of the accepted connection, and passes that URI to the CurrentContainer interface. This creates a com.yahoo.jdisc.core.ContainerSnapshot that holds a reference to the Container that is currently active, and resolves the appropriate BindingSet for the given URI through the Application's BindingSetSelector. This snapshot becomes the context of the new Request to ensure that all further processing of that Request happens within the same Container instace. Finally, the appropriate RequestHandler is resolved by the selected BindingSet, and the Request is dispatched.

private final ServerProvider server;

@Inject
MyApplication(CurrentContainer container) {
    server = new MyServerProvider(container);
    server.start();
}

ClientProvider

A ClientProvider extends the RequestHandler interface, adding a method for initiating the startup of the provider. This is to allow an Application to develop a common ClientProvider install path. As opposed to RequestHandlers that are bound to URIs with the "localhost" hostname that the ServerProviders use when creating a Request, a ClientProvider is typically bound using a hostname wildcard (the '*' character). Because BindingSet considers a wildcard match to be weaker than a verbatim match, only Requests with URIs that are not bound to a local RequestHandler are passed to the ClientProvider.

private final ClientProvider client;

@Inject
MyApplication(ContainerActivator activator, CurrentContainer container) {
    client = new MyClientProvider();
    client.start();

    ContainerBuilder builder = activator.newContainerBuilder();
    builder.serverBindings().bind("http://localhost/*", new MyRequestHandler());
    builder.clientBindings().bind("http://*/*", client);
    activator.activateContainer(builder);
}

Because the dispatch to a ClientProvider uses the same mechanics as the dispatch to an ordinary RequestHandler (i.e. the BindingSet), it is possible to create a test-mode BindingSet and a test-aware BindingSetSelector which dispatches to mock-up RequestHandlers instead of remote servers. The immediate benefit of this is that regression tests can be run on an Application otherwise configured for production traffic, allowing you to stress actual production code instead of targeted-only unit tests. This is how you would install a custom BindingSetSelector:

@Inject
MyApplication(ContainerActivator activator, CurrentContainer container) {
    ContainerBuilder builder = activator.newContainerBuilder();
    builder.clientBindings().bind("http://bing.com/*", new BingClientProvider());
    builder.clientBindings("test").bind("http://bing.com/*", new BingMockupProvider());
    builder.guiceModules().install(new MyBindingSetSelector());
    activator.activateContainer(builder);
}
See Also:
com.yahoo.jdisc, com.yahoo.jdisc.application, com.yahoo.jdisc.handler