public interface MatsEndpoint<R,S> extends MatsConfig.StartStoppable
MatsFactory
(or use the Spring integration).
Implementation Note: It shall be possible to use instances of MatsEndpoint
as keys in a
HashMap
, i.e. their equals and hashCode should remain stable throughout the life of the MatsFactory -
and similar instances but with different MatsFactory are not equals. Depending on the implementation, instance
equality may be sufficient.Modifier and Type | Interface and Description |
---|---|
static interface |
MatsEndpoint.DetachedProcessContext
The part of
MatsEndpoint.ProcessContext that exposes the "getter" side of the context, which enables it to be exposed
outside of the process lambda. |
static interface |
MatsEndpoint.EndpointConfig<R,S>
Provides for both configuring the endpoint (before it is started), and introspecting the configuration.
|
static interface |
MatsEndpoint.MatsObject
For the incoming message type, this represents the equivalent of Java's
Object - a "generic" incoming
message whose type is not yet determined. |
static class |
MatsEndpoint.MatsRefuseMessageException
Can be thrown by the
MatsEndpoint.ProcessLambda of the MatsStage s to denote that it would prefer this message
to be instantly put on a Dead Letter Queue (the stage processing, including any database actions, will
still be rolled back as with any other exception thrown out of a ProcessLambda). |
static interface |
MatsEndpoint.ProcessContext<R>
A way for the process stage to communicate with the library, providing methods to invoke a request, send a reply
(for multi-stage endpoints, this provides a way to do a "early return"), initiate a new message etc.
|
static class |
MatsEndpoint.ProcessContextWrapper<R>
A base Wrapper for
MatsEndpoint.ProcessContext , which simply implements ProcessContext, takes a ProcessContext
instance and forwards all calls to that. |
static interface |
MatsEndpoint.ProcessLambda<R,S,I>
The lambda that shall be provided by the developer for the process stage(s) for the endpoint - provides the
context, state and incoming message DTO.
|
static interface |
MatsEndpoint.ProcessReturnLambda<R,S,I>
Specialization of
ProcessLambda that makes it possible to do a "return
replyDto" at the end of the stage, which is just a convenient way to invoke
MatsEndpoint.ProcessContext.reply(Object) . |
static interface |
MatsEndpoint.ProcessSingleLambda<R,I>
Specialization of
ProcessLambda which does not have a state, and have the same
return-semantics as ProcessReturnLambda - used for single-stage
endpoints as these does not have multiple stages to transfer state between. |
static interface |
MatsEndpoint.ProcessTerminatorLambda<S,I>
Specialization of
ProcessLambda which does not have reply specified - used for
terminator endpoints. |
Modifier and Type | Method and Description |
---|---|
void |
finishSetup()
Should be invoked when all stages has been added.
|
MatsEndpoint.EndpointConfig<R,S> |
getEndpointConfig() |
MatsFactory |
getParentFactory() |
java.util.List<MatsStage<R,S,?>> |
getStages() |
<I> MatsStage<R,S,I> |
lastStage(java.lang.Class<I> incomingClass,
java.util.function.Consumer<? super MatsStage.StageConfig<R,S,I>> stageConfigLambda,
MatsEndpoint.ProcessReturnLambda<R,S,I> processor)
Variation of
lastStage(Class, ProcessReturnLambda) that can be configured "on the fly". |
<I> MatsStage<R,S,I> |
lastStage(java.lang.Class<I> incomingClass,
MatsEndpoint.ProcessReturnLambda<R,S,I> processor)
Adds the last stage to a multi-stage endpoint, which also
finishes setup of the endpoint. |
boolean |
remove(int gracefulShutdownMillis)
Should most probably only be used for testing!
First invokes
stop(gracefulShutdownMillis) , and if successful removes the endpoint from
its MatsFactory. |
<I> MatsStage<R,S,I> |
stage(java.lang.Class<I> incomingClass,
java.util.function.Consumer<? super MatsStage.StageConfig<R,S,I>> stageConfigLambda,
MatsEndpoint.ProcessLambda<R,S,I> processor)
Variation of
stage(Class, ProcessLambda) that can be configured "on the fly". |
<I> MatsStage<R,S,I> |
stage(java.lang.Class<I> incomingClass,
MatsEndpoint.ProcessLambda<R,S,I> processor)
Adds a new stage to a multi-stage endpoint.
|
void |
start()
Starts the endpoint (unless
finishSetup() has NOT been invoked), invoking MatsStage.start() on
any not-yet started stages of the endpoint (which should be all of them at application startup). |
boolean |
stop(int gracefulShutdownMillis)
Stops the endpoint, invoking
MatsStage.stop(int) on all MatsStage s. |
boolean |
waitForReceiving(int timeoutMillis)
Waits till all stages of the endpoint has entered their receive-loops, i.e.
|
MatsEndpoint.EndpointConfig<R,S> getEndpointConfig()
MatsFactory getParentFactory()
MatsFactory
.<I> MatsStage<R,S,I> stage(java.lang.Class<I> incomingClass, MatsEndpoint.ProcessLambda<R,S,I> processor)
finishSetup()
afterwards - or you could instead use the lastStage(Class, ProcessReturnLambda)
variant which does this automatically.I
- the type of the incoming DTO. The very first stage's incoming DTO is the endpoint's incoming DTO. If
the special type MatsEndpoint.MatsObject
, this stage can take any type.processor
- the lambda that will be invoked when messages arrive in the corresponding queue.MatsEndpoint.MatsObject
<I> MatsStage<R,S,I> stage(java.lang.Class<I> incomingClass, java.util.function.Consumer<? super MatsStage.StageConfig<R,S,I>> stageConfigLambda, MatsEndpoint.ProcessLambda<R,S,I> processor)
stage(Class, ProcessLambda)
that can be configured "on the fly".<I> MatsStage<R,S,I> lastStage(java.lang.Class<I> incomingClass, MatsEndpoint.ProcessReturnLambda<R,S,I> processor)
finishes setup
of the endpoint.
Note that the last-stage concept is just a convenience that lets the developer reply from the endpoint with a
return replyDTO
statement - you may just as well add a standard stage, and invoke the
MatsEndpoint.ProcessContext.reply(Object)
method. Note: If using a normal stage as the last stage, you must remember
to invoke finishSetup()
afterwards, as that is then not done automatically.I
- the type of the incoming DTO. The very first stage's incoming DTO is the endpoint's incoming DTO. If
the special type MatsEndpoint.MatsObject
, this stage can take any type.processor
- the lambda that will be invoked when messages arrive in the corresponding queue.<I> MatsStage<R,S,I> lastStage(java.lang.Class<I> incomingClass, java.util.function.Consumer<? super MatsStage.StageConfig<R,S,I>> stageConfigLambda, MatsEndpoint.ProcessReturnLambda<R,S,I> processor)
lastStage(Class, ProcessReturnLambda)
that can be configured "on the fly".java.util.List<MatsStage<R,S,?>> getStages()
MatsStage
s, representing all the stages of the endpoint. The order is the same as the
order in which the stages will be invoked. For single-staged endpoints and terminators, this list is of
size 1.void finishSetup()
lastStage(Class, ProcessReturnLambda)
, which again implies that it will be invoked when creating
single-stage endpoints
and
terminators
and
subscription
terminators
.
This sets the state of the endpoint to "finished setup", and will invoke start()
on the endpoint,
unless MatsFactory.holdEndpointsUntilFactoryIsStarted()
has been invoked prior to creating the
endpoint.
You may implement "delayed start" of an endpoint by not invoking finishedSetup() after setting it up.
Taking into account the first chapter of this JavaDoc, note that you must then only use the
staged
type of Endpoint setup, as the others implicitly invokes
finishSetup(), and also not invoke lastStage
on it as this
also implicitly invokes finishSetup(). When setting an Endpoint up without calling finishSetup(), even when
MatsFactory.start()
is invoked, such a not-finished endpoint will then not be started. You may then later
invoke finishSetup(), e.g. when any needed caches are finished populated, and the endpoint will then be finished
and started.
Another way to implement "delayed start" is to obviously just not create the endpoint until later: MatsFactory
has no "that's it, now all endpoints must have been created"-lifecycle stage, and can fire up new
endpoints until the JVM is dead.void start()
finishSetup()
has NOT been invoked), invoking MatsStage.start()
on
any not-yet started stages of the endpoint (which should be all of them at application startup).start
in interface MatsConfig.StartStoppable
boolean waitForReceiving(int timeoutMillis)
MatsStage.waitForReceiving(int)
on all MatsStage
s of the endpoint.
Note: This method makes most sense for
SubscriptionTerminators
: These are based on MQ Topics, whose semantics are that if you do not listen right when
someone says something, you will not hear it. This means that a SubscriptionTerminator will never receive a
message that was sent before it had started the receive-loop. Thus, if you in a service-"boot" phase send
a message whose result will come in to a SubscriptionTerminator, you will not receive this result if the
receive-loop has not started. This is relevant for certain cache setups where you listen for event updates, and
when "booting" the cache, you need to be certain that you have started receiving updates before asking for the
"initial load" of the cache. It is also relevant for tools like the MatsFuturizer
, which uses a
node-specific Topic for the final reply message from the requested service; If the SubscriptionTerminator has not
yet made it to the receive-loop, any replies will simply be lost and the future never completed.
Note: Currently, this only holds for the initial start. If the entity has started the receive-loop at some point,
it will always immediately return - even though it is currently stopped.waitForReceiving
in interface MatsConfig.StartStoppable
timeoutMillis
- number of milliseconds before giving up the wait, returning false
. 0 is indefinite
wait, negative values are not allowed.true
if successfully started listening for messages).boolean stop(int gracefulShutdownMillis)
MatsStage.stop(int)
on all MatsStage
s.stop
in interface MatsConfig.StartStoppable
gracefulShutdownMillis
- number of milliseconds to let the stage processors wait after having asked for them to shut down,
and interrupting them if they have not shut down yet.true
if successfully stopped all listening
threads).boolean remove(int gracefulShutdownMillis)
stop(gracefulShutdownMillis)
, and if successful removes the endpoint from
its MatsFactory. This enables a new endpoint to be registered with the same endpointId as the one removed (which
otherwise is not accepted). This might be of interest in testing scenarios, where you want to change the
implementation of an endpoint from one test to another. There is currently no known situation where this makes
sense to do "in production": Once the system is set up with the correct endpoints, it should most probably stay
that way!stop(int gracefulShutdownMillis)
was successful, and thus whether the endpoint was
removed from its MatsFactory.