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:
Open
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.
Step 3 (optional): Do not override
EReplier interface methods. Instead, set callbacks
using requestCallback(RequestCallback) and/or
cancelRequestCallback(CancelRequestCallback) passing
in Java lambda expressions.
Step 4: Advertise this
replier to eBus. This allows eBus to match repliers with
requestors.
Step 5: 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 6:
Send one or
more reply messages back to the
requestor.
Step 7: When the replier is shutting down,
retract the reply advertisement and
close the feed.
EReplyFeedimport 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 {
public CatalogReplier(final String subject, final FeedScope scope) {
mKey = new EMessageKey(com.acme.CatalogOrder.class, subject); mScope = scope;
mFeed = null;
mRequests = new ArrayList<>();
}
@Override
public void startup() {
try {
Step 2: Open a reply feed for reply message key.
// This advertisement has no associated ECondition; passing in null.
mFeed = EReplyFeed.open(this, mKey, mScope, null);
Step 3: EReplier interface methods overridden.
Step 4: Advertise reply feed.
mFeed.advertise();
mFeed.updateFeedState(EFeedState.UP);
} catch (IllegalArgumentException argex) {
// Advertisement failed. Place recovery code here.
}
}
Step 5: 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 EReplyFeed feed) {
// 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 6: Send one or more reply messages back to requestor.
public void orderReply(final EReplyFeed.ERequest request, final boolean status, final String reason) {
final ERequestAd ad = mRequests.get(request);
if (mRequests.contains(request) && request.isActive()) {
request.reply(new OrderReply(status, reason), ad);
// If the request processing is complete, remove the request.
if (status.isFinal()) {
mRequests.remove(request);
}
}
}
@Override
public void shutdown() {
final String subject = mKey.subject();
EReplyMessage reply;
// While eBus will does this for us, it is better to do it ourselves.
for (EReplyFeed.ERequest request : mRequests) {
reply = new EReplyMessage(subject, ReplyStatus.ERROR, "shutting down");
request.reply(reply);
}
mRequests.clear();
Step 7: When shutting down, either unadvertise or close reply feed.
if (mFeed != null) {
mFeed.close();
mFeed = null;
}
}
private final EMessageKey mKey;
private final FeedScope mScope;
private EReplyFeed mFeed;
private final List<EReplyFeed.ERequest> mRequests;
}EReplier,
ERequestor,
ERequestFeed| Modifier and Type | Class and Description |
|---|---|
static class |
EReplyFeed.ERequest
|
protected static class |
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 static List<EFeed> |
mAdvertisers
Track the advertised feeds in order to generate
advertise messages. |
protected 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.
|
mEClient, mFeedId, mFeedState, mInPlace, mIsActive, mScope, NO_CONDITION, NOTIFY_METHOD| Modifier and Type | Method and Description |
|---|---|
int |
activationCount()
Returns the feed activation count.
|
void |
advertise()
Advertises this replier fed to the associated request
subject.
|
void |
cancelRequestCallback(CancelRequestCallback cb)
Puts the cancel request callback in place.
|
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.
|
String |
messageSubject()
Returns the feed
message key subect. |
static EReplyFeed |
open(EReplier client,
EMessageKey key,
EFeed.FeedScope scope,
ECondition condition)
Returns a reply advertiser feed for the specified request
message class and subject.
|
static EReplyFeed |
open(EReplier client,
EMessageKey key,
EFeed.FeedScope scope,
ECondition condition,
EClient.ClientLocation l,
MessageType dataType,
boolean isMulti)
Returns a reply advertiser feed for the specified request
message class and subject.
|
void |
requestCallback(RequestCallback cb)
Puts the new request callback in place.
|
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, checkScopes, clientId, close, defaultDispatcher, eClient, equals, feedId, feedState, findKeys, findKeys, findKeys, hashCode, inPlace, isActive, isFeedUp, isOverridden, loadKeys, location, register, register, register, scope, shutdown, shutdown, shutdownAll, startup, startup, startupAll, storeKeys, storeKeys, storeKeysprotected static final List<EFeed> mAdvertisers
advertise messages.protected final ESingleFeed.FeedType mFeedType
protected final net.sf.eBus.client.ESubject mSubject
feed type.protected int mActivationCount
protected void inactivate()
inactivate in class EFeedEFeed.close()public boolean isAdvertised()
true if this reply feed is both open and
advertised; otherwise, returns false.isAdvertised in interface IEReplyFeedtrue if this reply feed is open and
advertised.public void requestCallback(RequestCallback cb)
cb is
not null, requests will be passed to cb
rather than
EReplier.request(EReplyFeed.ERequest). A
null cb means that requests are passed to the
EReplier.request(EReplyFeed.ERequest) override.requestCallback in interface IEReplyFeedcb - the request callback. May be null.IllegalStateException - if this feed is either closed or advertised.public void cancelRequestCallback(CancelRequestCallback cb)
cb
is not null, requests will be passed to cb
rather than
EReplier.cancelRequest(EReplyFeed.ERequest). A
null cb means that cancellations are passed to the
EReplier.cancelRequest(EReplyFeed.ERequest)
override.cancelRequestCallback in interface IEReplyFeedcb - the cancel request callback. May be
null.IllegalStateException - if this feed is either closed or 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 IEReplyFeedupdate - the new reply feed state.NullPointerException - if update is null.IllegalStateException - if this feed was closed and is inactive or is not
advertised.public static EReplyFeed open(EReplier client, EMessageKey key, EFeed.FeedScope scope, ECondition condition)
advertise()
on the returned feed in order to start receiving the
specified request messages.client - the application object subscribing to the
request. May not be null.key - the request message class and subject.
May not be null and must reference a request
message class.scope - whether this feed supports only local
clients, remote clients, or both.condition - accept request messages only if the
messages passes this condition. May be null. If
null, then the
default condition which accepts all
request messages is used.NullPointerException - if any of the required parameters is null.IllegalArgumentException - if any of the given parameters is invalid.advertise(),
EFeed.close()public static EReplyFeed open(EReplier client, EMessageKey key, EFeed.FeedScope scope, ECondition condition, EClient.ClientLocation l, MessageType dataType, boolean isMulti)
advertise()
on the returned feed in order to start receiving the
specified request messages.
This method does not parameter validation since this is
a package private method.
client - the application object subscribing to the
request. May not be null.key - the request message class and subject.
May not be null and must reference a request
message class.scope - whether this feed supports only local
clients, remote clients, or both.condition - accept request messages only if the
messages passes this condition. May be null. If
null, then the
default condition which accepts all
request messages is used.l - client location.dataType - the request message type. Used to
determine if the reply message is in the request message
EReplyInfo list.isMulti - true if this is part of a multiple
key feed. If true, this feed is not added to the
client feed list.public void advertise()
advertise in interface IEReplyFeedIllegalStateException - 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 IEReplyFeedIllegalStateException - if this feed was closed and is inactive.advertise(),
EFeed.close()public String toString()
public final EMessageKey key()
EPublishFeed, then a
notification
message key is returned.public final String messageSubject()
message key subect.public final int activationCount()
Copyright © 2019. All rights reserved.