MHonArc v2.5.2 -->
wsia message
[Date Prev]
| [Thread Prev]
| [Thread Next]
| [Date Next]
--
[Date Index]
| [Thread Index]
| [Elist Home]
Subject: [wsia][wsrp][wsrp-wsia joint interfaces]: An alternative
The attached is an alternative proposal to draft 0.1.2. Its a more
simplified interface based on a (web) service model (not OO). It
assumes the consumer provides the (transient) entity key to the
producer. For simplicity I haven't defined these as bulk operations.
My personal preference is if we want to support bulk operations then
such operations would be added vs. replace these. Also I have taken a
little different tack in defining each methods incoming parameters. I
have separated what I thought were the logical base parameters to the
method from the contextual parameters -- those that identify the
consumer, the user etc. This later group is packaged into a single data
element as a Call Context. As the context varies a little for each
method, each method has its own call context defined.
Also, I have left out the Action method pending my understanding if/why
we need it. Finally, so I can get this out today, I leave describe()
and setProperties() as an exercise for the reader.
I hope you will find this API not only a little simplier/clearer but
also more manageable. I think it creates far fewer "dynamic" references
that hopefully lead to more performant and scalable systems. Please let
me know what you think.
-Mike-
The following is a counter-proposal to draft 0.1.2. Its a more simplified
interface based on a (web) service model (not OO). It assumes the
consumer provides the (transient) entity key to the producer. For
simplicity I haven't defined these as bulk operations. My personal
preference is if we want to support bulk operations then such operations
would be added vs. replace these. Also I have taken a little different
tack in defining each methods incoming parameters. I have separated
what I thought were the logical base parameters to the method from the
contextual parameters -- those that identify the consumer, the user etc.
This later group is packaged into a single data element as a Call Context.
As the context varies a little for each method, each method has its own
call context defined.
Also, I have left out the Action method pending my understanding if/why
we need it. Finally, so I can get this out today, I leave describe()
and setProperties() as an exercise for the reader.
I hope you will find this API not only a little simplier/clearer but
also more managable. It creates far fewer "dynamic" references that
hopefully lead to more performant and scalable systems. Please let
me know what you think.
-Mike-
References:
A reference is something that allows a consumer to identify an element
that is co-managed between the producer and the consumer. Currently
there are 4 references: ConsumerRef, SessionRef, PersistenceRef, and EntityRef.
each is represented as a String. The ConsumerRef identifies who the
consumer is. The SessionRef identifies a conversation between a consumer
and a producer. A PersistenceRef identifies a particular entities
persistent data. An EntityRef identifies a converstation between
a consumer and an entity within the producer.
The major model change here is that there is no longer a concept of
producer entity (instances). Rather we just exist in a world where
we reference elements that need to be identified between the producer and
the consumer. For producers managing a heterogeneous set of portlets,
each (type of) portlet is identified by an EntityType. Each portlet
(EntityType) is a single object ala a servlet. References are passed
to the portlet to allow it to establish its (data) context. A portlet
may maintain 2 types of data context, transient and persistent. All
transient data is scoped to a "session" that is managed/referred to via
the SessionRef. As sessions are (generally) shared across the entire
producer, a second reference, the entityRef is provided that allows a portlet
to safely partition a portion of the session data so that it is isolated/private
from other "entities". An "entity" (and its reference) in this case
is defined by the consumer and refers to runtime reference to an instance
of a particular type. Note: as sessions are scoped to a particular
consumer and entityRefs only exist to allow a portlet to namespace the
session entityRefs need only be unique within a given consumer session.
Ref extends String;
ConsumerRef extends Ref;
SessionRef extends Ref;
PersistenceRef extends Ref;
EntityRef extends Ref;
A single method is provided to tell the producer a reference has gone out
of scope. The method takes the reference itself and a reference type.
The reference type is used to figure out the type of the reference being
released (as the reference is just an ID/String). The ReleaseRefCtx
contains the contextual data this method (may) need to operate. In
this case I think it would just contain the ConsumerRef and UserIdentify.
void releaseRef(ReleaseRefCtx ctx, Ref ref, RefType type);
ConsumerIdentity
A consumer is identified either by a reference generated by the producer
in response to a registerConsumer call. This id may be as simple
as the consumer name passed into the call. The ConsumerProperties
are consistent with those defined in the original draft and include the
consumer name, vendor, etc. registerConsumer must return a non-null
value unless an exception is generated. The updateRegistration call is
used to update the registration of an existing consumer. We don't
allow a new reference to be generated. The Context parameter contains
the SessionRef in case information is cached in transient data and needs
updating as well. I.e. the philosophy is that sessions may be created
by the consumer at the first time the consumer talks to the producer once
registered -- as all subsequent calls (can) occur within the conversational
period they all receive a sessionRef.
ConsumerRef registerConsumer(ConsumerProperties consumer);
void updateRegistration(UpdateRegistrationCtx ctx, ConsumerRef
ref, ConsumerProperties consumer);
SessionsSessions represent a conversational period between a consumer and a
producer. The SessionRef allows the producer to maintain transient
state scoped to this conversation. Sessions only come into existence
via explicit request by the consumer. This means a consumer must
be informed by the producer that a session is desired. This can either
be done via meta data in the describe call or on demand. I.e.
all calls that can run receive a sessionRef can through a InvalidSession
exception. Consumers are expected to catch this exception, create
a (new) session and retry the operation.
The createSession call takes a context, a reference to the consumer
and the user identity.
SessionRef createSession(CreateSessionContext ctx);
CreateSessionContext
{
private ConsumerRef consumer;
private UserIdentify user;
}
PersistenceMany producers manage entities that require persistent data.
Some producers rely on having the consumer manage this persisitent data.
In this case, the producer/entity publishes a description of its data and
expects the consumer to pass the relevant values on request. Other
entities manage the data itself. The consumer defines when new persistent
instances come into existence. In the case the producer/entity manages
the data, the consumer requests the producer to create a new persistent
record and to return a reference to it. For convience, new records
can be created from old ones (by reference). The consumer is expected
to supply this reference back to the producer in subsequent operational
requests.
A new persistence reference is creaetd either from an existing one or
from scratch by identifying the type of persistent data. The type
is the entityType (aka the portlet ID). The values aer passed as
a single parameter (PersistenceType) that acts as a union. Either
the ref has a value or the entityType has a value.
The typeIsRef field allows the code to determine which element
is valid in the union.
Cloning is similar to creating except is cerates siblings rather then
children ( see the draft).
public PersistenceRef createPersistenceRef(CreatePersistenceRefCtx
ctx,
PersistenceType type, PersistentProperty[] values);
CreatePersistenceRefCtx
{
private ConsumerRef consumer;
private SessionRef session;
private UserIdentify user;
}
PersistenceType
{
private boolean typeIsRef;
private PersistenceRef ref;
private String entityType;
}
public PersistenceRef clonePersistenceRef(ClonePersistenceRefCtx
ctx,
PersistenceRef ref);
ClonePersistenceRefCtx
{
private ConsumerRef consumer;
private SessionRef session;
private UserIdentify user;
}
Operations:As I don't yet understand how Actions differ semantically from getFragment
(from a protocol perspective) the only operation I model here is getFragment.
getFragment takes a call context and request data.
The call context contains all the references that identify the context
of this call. This includes both an entityRef and entityType.
entityType is the portlet id; it identifies which portlet/entity is the
target of the request. entityRef is a consumer generated ID that
identifies a particular consumer instance of this entity. It can
be used by the producer to namespace/cerate a private space in the session
for storing entity specific transient data.
The request data is much like in the original draft -- its the data
that is particular to this request including parameters, attributes (headers),
modes/states, etc.
getFragment returns a FragmentResponse. This
includes responseProperties, the fragment itself, and persistentProperties.
The responseProperties are attribute/values returned to the consumer that
either identify information about the fragment (char set etc) or define
attribuets to be passed on subsequent requests to the same entityRef (aka
headers). The fragment is the content itself. The persistentProperties
is a property list of persistent values used to pass back nwe/updated values
when a consumer is maintaining the persisitent data on behalf of the producer/portlet.
public FragmentResponse getFragment(GetFragmentCtx ctx,
FragmentRequestData
parameters);
public class FragmentResponse
{
Property[] responseProperties;
String fragment;
PersistentProperty[] values;
}
public class GetFragmentCtx
{
private ConsumerRef consumerId;
private SessionRef sessionId;
private UserIdentify user;
private Ref entityRef;
private String entityType;
private PersistenceRef persistenceId; // passed
if portlet maintains data
private PersistenceProperties persistenceData;
// passed if consumer does
private PreambleData updateData; // update
the included session or
// persistent data before generating the fragment;
}
public class FragmentRequestData
{
private String charSet;
private String markupType;
private String locale;
private Boolean secureClientCommunications;
private Property[] headers;
private Property[] parameters;
private DeviceInfo clientDevice;
private Mode producerMode;
}
[Date Prev]
| [Thread Prev]
| [Thread Next]
| [Date Next]
--
[Date Index]
| [Thread Index]
| [Elist Home]
Powered by eList eXpress LLC