public final class EReplyFeed extends EFeed implements IEReplyFeed
EReplyFeed
is the application entry point for posting
replies to request messages
to
requestors. Follow these steps to use this feed:
Step 1: Implement the EReplier
interface.
Step 2:
Build
a reply feed for a given
EReplier
instance and
type+topic message key
. The condition is
optional and may be null
. If provided, then only
request messages satisfying the condition are forwarded to the
replier.
Use
EReplyFeed.Builder.cancelRequestCallback(CancelRequestCallback)
and
EReplyFeed.Builder.requestCallback(RequestCallback)
to set Java
lambda expressions used in place of EReplier
interface
methods.
Step 3: Advertise
this
replier to eBus. This allows eBus to match repliers with
requestors.
Step 4: Wait for
requests
to arrive. Keep the given EReplyFeed.ERequest
instance handy
because ERequest
is used to post reply messages back
to the requestor, not EReplyFeed
.
Step 5:
Send
one or
more reply
messages back to the
requestor.
Step 6: When the replier is shutting down,
retract
the reply advertisement and
close
the feed.
EReplyFeed
import java.util.ArrayList;
import java.util.List;
import net.sf.eBus.client.EFeed.FeedScope;
import net.sf.eBus.client.EReplier;
import net.sf.eBus.client.EReplyFeed;
import net.sf.eBus.messages.EReplyMessage
import net.sf.eBus.messages.EReplyMessage.ReplyStatus; import net.sf.eBus.messages.EMessageKey;
import net.sf.eBus.messages.ERequestMessage;
Step 1: Implement EReplier interface.
public class CatalogReplier implements EReplier {
private final EMessageKey mKey;
private final FeedScope mScope;
private EReplyFeed mFeed;
private final List<EReplyFeed.ERequest> mRequests;
public CatalogReplier(final String subject, final FeedScope scope) {
mKey = new EMessageKey(com.acme.CatalogOrder.class, subject);
mScope = scope;
mRequests = new ArrayList<>();
}
@Override
public void startup() {
try {
Step 2: Open a reply feed for reply message key. May override EReplier interfaces methods.
// This advertisement has no associated ECondition and uses EReplier interface method overrides.
mFeed = (EReplyFeed.builder()).target(this)
.messageKey(mKey)
.scope(mScope)
.build();
Step 3: Advertise reply feed.
mFeed.advertise();
mFeed.updateFeedState(EFeedState.UP);
} catch (IllegalArgumentException argex) {
// Advertisement failed. Place recovery code here.
}
}
Step 4: Wait for requests to arrive.
@Override
public void request(final EReplyFeed.ERequest request, final EReplyFeed feed) {
final ERequestMessage msg = request.request();
try {
mRequests.add(request);
startOrderProcessing(msg, request);
} catch (Exception jex) {
request.reply(new CatalogOrderReply(ReplyStatus.ERROR, // reply status.
jex.getMessage())); // reply reason.
}
}
@Override
public void cancelRequest(final EReplyFeed.ERequest request, final boolean mayRespond) {
// Is this request still active? It is if the request is listed.
if (mRequests.remove(request)) {
// Yes, try to stop the request processing.
try {
// Throws an exception if the request cannot be stopped.
stopOrderProcessing(request);
} catch (Exception jex) {
// Ignore since nothing else can be done.
}
}
}
Step 5: Send one or more reply messages back to requestor.
public void orderReply(final EReplyFeed.ERequest request, final ReplyStatus status, final String reason) {
final ERequestAd ad = mRequests.get(request);
if (mRequests.contains(request) && request.isActive()) {
request.reply((OrderReply.builder()).subject(mKey.subject())
.timestamp(Instant.now())
.replyStatus(status)
.replyReason(reason)
.build());
// If the request processing is complete, remove the request.
if (status.isFinal()) {
mRequests.remove(request);
}
}
}
@Override
public void shutdown() {
final String subject = mKey.subject();
// While eBus will does this for us, it is better to do it ourselves.
for (EReplyFeed.ERequest request : mRequests) {
request.reply((EReplyMessage.builder()).subject(subject)
.timestamp(Instant.now())
.replyStatus(ReplyStatus.ERROR)
.replyReason("shutting down")
.build());
}
mRequests.clear();
Step 6: When shutting down, either unadvertise or close reply feed.
if (mFeed != null) {
mFeed.close();
mFeed = null;
}
}
}
EReplier
,
ERequestor
,
ERequestFeed
Modifier and Type | Class and Description |
---|---|
static class |
EReplyFeed.Builder
EReplyFeed.Builder is now the preferred
mechanism for creating a EReplyFeed instance. |
static class |
EReplyFeed.ERequest
|
protected static class |
net.sf.eBus.client.ESingleFeed.FeedType
Enumerates the supported feed types.
|
EFeed.AbstractClientTask, EFeed.FeedScope, EFeed.NotifyTask, EFeed.StatusTask<T extends IEFeed>
Modifier and Type | Field and Description |
---|---|
protected int |
mActivationCount
Tracks the number of contra-feeds matched to this feed.
|
protected net.sf.eBus.client.ESingleFeed.FeedType |
mFeedType
Specifies whether this is a publish, subscribe, request,
or reply feed.
|
protected net.sf.eBus.client.ESubject |
mSubject
The feed interfaces with this eBus subject.
|
FEED_IS_INACTIVE, FEED_NOT_ADVERTISED, mEClient, mFeedId, mFeedState, mInPlace, mIsActive, mScope, NO_CONDITION, NOTIFY_METHOD, NULL_CLIENT
Modifier and Type | Method and Description |
---|---|
int |
activationCount()
Returns the feed activation count.
|
void |
advertise()
Advertises this replier fed to the associated request
subject.
|
static EReplyFeed.Builder |
builder()
Returns a new
EReplyFeed builder instance. |
protected void |
inactivate()
If the advertisement is in place, then un-advertises it,
sends a final error reply to all extant requests, and if
this feed's scope is local & remote or remote only,
removes this feed from the advertisers list.
|
boolean |
isAdvertised()
Returns
true if this reply feed is both open and
advertised; otherwise, returns false . |
EMessageKey |
key()
Returns the feed message key.
|
java.lang.String |
messageSubject()
Returns the feed
message key subect . |
java.lang.String |
toString()
Returns a containing the feed message key and data member
values.
|
void |
unadvertise()
Retracts this replier feed from the associated request
subject.
|
void |
updateFeedState(EFeedState update)
Updates the replier feed state to the given value.
|
addAllKeys, addKey, addListener, checkScopes, clientId, close, createDispatcher, defaultDispatcher, eClient, equals, feedId, feedState, findKeys, findKeys, findKeys, hashCode, inPlace, isActive, isFeedUp, isOverridden, loadKeys, location, register, register, register, removeListener, scope, setExhaust, shutdown, shutdown, shutdownAll, startup, startup, startupAll, storeKeys, storeKeys, storeKeys, subclassDistance
protected final net.sf.eBus.client.ESingleFeed.FeedType mFeedType
protected final net.sf.eBus.client.ESubject mSubject
feed type
.protected int mActivationCount
protected void inactivate()
inactivate
in class EFeed
EFeed.close()
public boolean isAdvertised()
true
if this reply feed is both open and
advertised; otherwise, returns false
.isAdvertised
in interface IEReplyFeed
true
if this reply feed is open and
advertised.public void updateFeedState(EFeedState update)
update
equals the currently stored reply feed
state, nothing is done. Otherwise, the updated value is
stored. If this feed is advertised to the server and
the subscription feed is up, then this update is forwarded
to subscribed requestors.updateFeedState
in interface IEReplyFeed
update
- the new reply feed state.java.lang.NullPointerException
- if update
is null
.java.lang.IllegalStateException
- if this feed was closed and is inactive or is not
advertised.public static EReplyFeed.Builder builder()
EReplyFeed
builder instance. This
instance should be used to build a single reply feed
instance and not used to create multiple such feeds.public void advertise()
advertise
in interface IEReplyFeed
java.lang.IllegalStateException
- if this feed is closed or if the client did not override
EReplier
methods nor put the required callbacks in
place.unadvertise()
,
updateFeedState(EFeedState)
,
EFeed.close()
public void unadvertise()
unadvertise
in interface IEReplyFeed
java.lang.IllegalStateException
- if this feed was closed and is inactive.advertise()
,
EFeed.close()
public java.lang.String toString()
public final EMessageKey key()
EPublishFeed
, then a
notification
message key is returned.public final java.lang.String messageSubject()
message key subect
.public final int activationCount()
Copyright © 2001 - 2024. Charles W. Rapp. All rights reserved.