Package org.forgerock.services.routing
Class AbstractRouter<T extends AbstractRouter<T,R,H,D>,R,H,D>
java.lang.Object
org.forgerock.services.routing.AbstractRouter<T,R,H,D>
- Type Parameters:
T
- The type of the router.R
- The type of the request.H
- The type of the handler that will be used to handle routing requests.D
- The type of descriptor object that the APIs supported by this router can be described using.
- All Implemented Interfaces:
Describable<D,
,R> Describable.Listener
public abstract class AbstractRouter<T extends AbstractRouter<T,R,H,D>,R,H,D>
extends Object
implements Describable<D,R>, Describable.Listener
An abstract base class for implementing routers. Routers are common in applications which need to process incoming
requests based on varying criteria such as the target endpoint, API version expectations, client criteria (e.g.
source address), etc. This base class is designed to be protocol and framework independent. Frameworks should
sub-class an abstract router in order to provide framework specific behavior.
Generally speaking a router comprises of a series of routes, each of which is composed of a RouteMatcher
and a handler (H). When a request (R) is received the router invokes each RouteMatcher
to see if it
matches and then invokes the associated handler if it is the best match.
Concrete implementations of AbstractRouter
existing in both CHF
and CREST.
-
Nested Class Summary
Nested classes/interfaces inherited from interface org.forgerock.services.descriptor.Describable
Describable.Listener
-
Field Summary
Modifier and TypeFieldDescriptionprotected D
Api of the current router.protected final RouteMatcher<R>
Matches the current route. -
Constructor Summary
ModifierConstructorDescriptionprotected
Creates a new abstract router with no routes defined.protected
AbstractRouter
(AbstractRouter<T, R, H, D> router) Creates a new router containing the same routes and default route as the provided router. -
Method Summary
Modifier and TypeMethodDescriptionfinal T
addAllRoutes
(T router) Adds all of the routes defined in the provided router to this router.void
addDescriptorListener
(Describable.Listener listener) Add a listener for API Descriptor changes.final T
addRoute
(RouteMatcher<R> matcher, H handler) Adds a new route to this router for the provided handler.api
(ApiProducer<D> producer) Provide the API description for the component.protected D
buildApi
(ApiProducer<D> producer) Build an api with a givenApiProducer
.getBestApiRoute
(Context context, R request) Get the best route for an API request.getBestRoute
(Context context, R request) Finds the best route that matches the given request based on the route matchers of the registered routes.protected final Map<RouteMatcher<R>,
H> Gets all registered routes on this router.protected abstract Pair<RouteMatcher<R>,
H> Return aDescribable
handler that returns thisAbstractRouter
's internal api description from theDescribable.handleApiRequest(Context, Object)
method.protected abstract T
getThis()
Returns thisAbstractRouter
instance, typed correctly.handleApiRequest
(Context context, R request) Handle a request for the API Descriptor.void
Implement this method to handle changes to API Descriptors.final T
Removes all of the routes from this router.void
removeDescriptorListener
(Describable.Listener listener) Remove a listener from API Descriptor changes.final boolean
removeRoute
(RouteMatcher<R>... routes) Removes one or more routes from this router.final T
setDefaultRoute
(H handler) Sets the handler to be used as the default route for requests which do not match any of the other defined routes.protected abstract RouteMatcher<R>
uriMatcher
(RoutingMode mode, String pattern) Create a URI matcher suitable for the request type<R>
.
-
Field Details
-
thisRouterUriMatcher
Matches the current route. -
api
Api of the current router.
-
-
Constructor Details
-
AbstractRouter
protected AbstractRouter()Creates a new abstract router with no routes defined. -
AbstractRouter
Creates a new router containing the same routes and default route as the provided router. Changes to the returned router's routing table will not impact the provided router.- Parameters:
router
- The router to be copied.
-
-
Method Details
-
getThis
Returns thisAbstractRouter
instance, typed correctly.- Returns:
- This
AbstractRouter
instance.
-
getRoutes
Gets all registered routes on this router.- Returns:
- All registered routes.
-
addAllRoutes
Adds all of the routes defined in the provided router to this router. New routes may be added while this router is processing requests.- Parameters:
router
- The router whose routes are to be copied into this router.- Returns:
- This router instance.
-
addRoute
Adds a new route to this router for the provided handler. New routes may be added while this router is processing requests.The provided matcher can be used to remove this route later.
- Parameters:
matcher
- TheRouteMatcher
that will evaluate whether the incoming request matches this route.handler
- The handler to which matching requests will be routed.- Returns:
- This router instance.
-
setDefaultRoute
Sets the handler to be used as the default route for requests which do not match any of the other defined routes.- Parameters:
handler
- The handler to be used as the default route.- Returns:
- This router instance.
-
removeAllRoutes
Removes all of the routes from this router. Routes may be removed while this router is processing requests.- Returns:
- This router instance.
-
removeRoute
Removes one or more routes from this router. Routes may be removed while this router is processing requests.- Parameters:
routes
- TheRouteMatcher
s of the routes to be removed.- Returns:
true
if at least one of the routes was found and removed.
-
getBestRoute
protected Pair<Context,H> getBestRoute(Context context, R request) throws IncomparableRouteMatchException Finds the best route that matches the given request based on the route matchers of the registered routes. If no registered route matches at all then the default route is chosen, if present.- Parameters:
context
- The request context.request
- The request to be matched against the registered routes.- Returns:
- A
Pair
containing the decoratedContext
and the handler which is the best match for the given request ornull
if no route was found. - Throws:
IncomparableRouteMatchException
- If any of the registeredRouteMatcher
s could not be compared to one another.
-
getBestApiRoute
protected Pair<Context,H> getBestApiRoute(Context context, R request) throws IncomparableRouteMatchException Get the best route for an API request. This is differs fromgetBestRoute(Context, Object)
in that it also checks to see whether this router itself is being addressed, and returns the merged descriptor for all the routes if so.- Parameters:
context
- The request context.request
- The request to be matched against the registered routes.- Returns:
- A
Pair
containing the decoratedContext
and the handler which is the best match for the given request ornull
if no route was found. - Throws:
IncomparableRouteMatchException
- If any of the registeredRouteMatcher
s could not be compared to one another.
-
getSelfApiHandler
Return aDescribable
handler that returns thisAbstractRouter
's internal api description from theDescribable.handleApiRequest(Context, Object)
method. All other methods should throw anUnsupportedOperationException
, as they should never be used.- Returns:
- The describable handler.
-
api
Description copied from interface:Describable
Provide the API description for the component. This method should perform the heavy-lifting of computing the API descriptor, and should be expected to be called rarely. Upstream handlers should call this method in order to compose all of their downstream API Descriptors into a single descriptor.- Specified by:
api
in interfaceDescribable<T extends AbstractRouter<T,
R, H, D>, R> - Parameters:
producer
- The API producer that provides general information to be built into the descriptor.- Returns:
- The description object.
-
uriMatcher
Create a URI matcher suitable for the request type<R>
.- Parameters:
mode
- The routing mode.pattern
- The pattern.- Returns:
- The matcher.
-
handleApiRequest
Description copied from interface:Describable
Handle a request for the API Descriptor. This method should not do any computation, but should return the already computed descriptor.- Specified by:
handleApiRequest
in interfaceDescribable<T extends AbstractRouter<T,
R, H, D>, R> - Parameters:
context
- The request context.request
- The request.- Returns:
- The descriptor.
-
addDescriptorListener
Description copied from interface:Describable
Add a listener for API Descriptor changes. The described object should call all the listeners.- Specified by:
addDescriptorListener
in interfaceDescribable<T extends AbstractRouter<T,
R, H, D>, R> - Parameters:
listener
- The listener.
-
removeDescriptorListener
Description copied from interface:Describable
Remove a listener from API Descriptor changes.- Specified by:
removeDescriptorListener
in interfaceDescribable<T extends AbstractRouter<T,
R, H, D>, R> - Parameters:
listener
- The listener.
-
notifyDescriptorChange
public void notifyDescriptorChange()Description copied from interface:Describable.Listener
Implement this method to handle changes to API Descriptors.- Specified by:
notifyDescriptorChange
in interfaceDescribable.Listener
-
buildApi
Build an api with a givenApiProducer
.- Parameters:
producer
- The given ApiProducer to use.- Returns:
- an api.
-