You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@abdera.apache.org by James M Snell <ja...@gmail.com> on 2008/01/22 07:40:59 UTC

Server Refactoring - Overview

Ok, the server refactoring is coming along very well I think.  Thus far, 
I've been able to greatly simplify the overall design, as well as 
integrate the approaches implemented by Dan and the google feed-server 
team while still maintaining the flexibility of the original framework.

The main components of the refactored design are:

  * AbderaServlet
  * ServiceContext
  * Provider
  * WorkspaceManager
  * CollectionAdapter
  * RequestContext
  * ResponseContext
  * Target
  * Resolver<Target>
  * Resolver<Subject>

For the overwhelming majority of implementations, all an end developer 
will need to do is implement a CollectionAdapter, provide a 
TargetResolver, and glue the two together using a ServiceContext.

The examples in the server_refactor test cases illustrates the three 
fundamental approaches.

The application flow is simple:

  * The AbderaServlet receives a request and creates a ServiceContext
  * The ServiceContext creates a Provider instance
  * The Provider instance uses it's associated WorkspaceManager to
    select a CollectionAdapter.
  * Once the CollectionAdapter is selected, the Provider forwards the
    request on to the appropriate method

In some cases, the Provider and the WorkspaceManager will be the same 
object.  In other cases, the Provider and the WorkspaceManager will be 
separate.

Simple
------

In the Simple example, the developer implements a CollectionAdapter, a 
Provider and a ServiceContext.

The CollectionAdapter provides the guts of the implementation, providing 
implementations for each of the main prototocol operations such as 
getFeed, getEntry, etc.  These are the methods that used to exist on the 
old style provider interface.

The Provider extends AbstractWorkspaceProvider which means the Provider 
is acting as it's own WorkspaceManager.

The Provider/WorkspaceManager dispatches requests to the SimpleAdapter 
implementation.

The SimpleServiceContext glues the Provider to the appropriate target 
resolver.

Default
-------

In the Default example, the developer uses the same CollectionAdapter 
implementation used in the simple example but uses the DefaultProvider 
class.

The Default example is similar in nature to the CollectionProvider stuff 
implemented by Dan in that it is the DefaultProvider's job to handle 
things like the creation of the Service document based on metadata 
provided by the developer.

The simple and default examples are nearly identical with the exception 
that the default example supports multiple workspaces and collections.

Basic
-----

The basic example (which is poorly named, I know) is essentially the 
google feed-server stuff, slightly modified so that it sits on top of 
the default provider implementation.

The properties file based deployment is kept intact, but the Adapter 
interface is replaced by the BasicAdapter abstract class, which is an 
abstract CollectionAdapter implementation that defines the same abstract 
methods defined by the google feed-server Adapter interface.  Existing 
google feed-server Adapter implementations can be ported to this design 
simply by replacing "implements Adapter" with "extends BasicAdapter".

The implementation has been further modified to support the creation of 
a service document.  The code will read all of the *.properties files 
for the adapters and will generate a service document with one workspace 
and one collection per configured adapter.

Service Documents
-----------------

In this design, the Provider is responsible for serving the service 
documents.  This means that the service document support will vary 
depending on the capabilities of the Provider implementation.

CollectionAdapters
------------------

In each of the three approaches, the same CollectionAdapter interface is 
used.  Also, with the possible exception of URI patterns used for links, 
CollectionAdapters should be independent of the Provider implementation 
used.  We need to find a more elegant way of tying Target Resolvers and 
Collection Adapters together while at the same time making it easier to 
manage links, but that can come later.  The more important thing is that 
once a CollectionAdapter is implementation, we should be able to use it 
regardless of which of the three models are selected.

Media Collections
-----------------

The basic CollectionAdapter interface does not support media operations. 
  If you want to implement support for media collections, the 
CollectionAdapter has to implement the MediaCollectionAdapter interface. 
  The reason for this separation is to reduce the complexity of the 
simplest Atompub implementations that will only ever support Atom entries.

Transactional
-------------

CollectionAdapter implementations can implement the Transactional 
interface if they wish to support transactional start/end/compensate 
semantics.  Provider implementations SHOULD call Transactional.start() 
before delegating to the CollectionAdapter method and 
Transactional.end() after delegating.  If an error occurs, the Provider 
SHOULD call Transactional.compensate().

- James

Re: Feedback round 2 [was Re: Server Refactoring - Overview]

Posted by Vasu Nori <va...@gmail.com>.
never mind my prev email. found the change branch with refactored code.



On Jan 22, 2008 11:17 AM, Vasu Nori <va...@gmail.com> wrote:

> James/Dan
>
> I have just had a chance to look at this email thread about server
> refactoring work.
> Sounds great. can't wait to see the new code and figure out how google
> feedserver code can fit in..
>
> Is this code in trunk or in some other change-branch?
> I got the latest from trunk - but can't find the changes you are talking
> about.
>
> any pointers?
>
> thanks
>
>
> On Jan 22, 2008 8:20 AM, James M Snell < jasnell@gmail.com> wrote:
>
> >
> > Dan Diephouse wrote:
> > > Looking good. But even more new comments! Hopefully you aren't sick of
> >
> > > me yet :-)
> > >
> >
> > Never!  Of course, large payments of small unmarked bills would help ;-)
> >
> > > Can we collapse ServiceContext and Provider? I would propose then that
> > > Provider gets getters/setters for Resolver<Subject>/<Target>. If we
> > did
> > > this we could get rid of ServiceContext too I think -- which would
> > > remove one more step for the user. I did a similar thing with when I
> > > made it implement Resolver<Target>. While I think this should be
> > > pluggable, I really think users should not have to configure a
> > resolver
> > > by default.
> > >
> >
> > Quite possibly. Will take a look today.
> >
> > > Along these lines I think we should remove the instantiation code
> > which
> > > is in DefaultServiceContext. IMO this is the job of a container of
> > some
> > > sort. I mean container in the broadest sense here.  For instance, I
> > > think it could be wrapped up in something like a
> > > PropertiesProviderBuilder. It could then configure a whole provider
> > > instance - including resolvers, workspace manager, and
> > collectionadapters.
> > >
> >
> > Agreed.
> >
> > > Transactional.begin/end needs to take RequestContext so I can store a
> > > JCR session in it.
> > >
> >
> > Ok, will add that today.
> >
> > > The JCR tests provide a good means to test if the basic
> > ServiceProvider
> > > stuff I wrote still roughly works.
> > >
> >
> > Well, it would need to be ported to the new model as the interfaces have
> >
> >  changed.  Would you like to take a stab at that?  Doing so would help
> > you get a better feeling for the new design.
> >
> > > My feeling is that CollectionInfo should not extend CollectionAdapter.
> >
> > > While I agree that people will probably implement both CollectionInfo
> > > and CollectionAdapter by default, sometimes you want to just return
> > the
> > > metadata.
> > >
> >
> > Agreed.  CollectionInfo can have a getCollectionAdapter method to
> > connect the two.
> >
> > > Re: BasicAdapter - I'm still unconvinced about this API and its
> > ability
> > > to support the necessary semantics for generic APP stores.
> > >
> >
> > Ditto.
> >
> > > CollectionAdapterManager should be in the basic package if we keep the
> > > basic stuff around.
> > >
> >
> > Take another look at CAM; I modified it so that it works generically
> > with any CollectionAdapter, not just BasicAdapter.  This would allow any
> > Provider implementation to use the properties file deployment mechanism
> > independently of whether the BasicAdapter interface is used.
> >
> > > I get the feeling that
> > > WorkspaceManager.checkMethod/checkTarget/getMethods can all probably
> > go.
> > > Could we not work that logic into the
> > CollectionAdapter.extensionRequest?
> > >
> >
> > Not sure about this.
> >
> > > I still don't think its a good idea for a Provider to act as its own
> > > WorkspaceManager per my previous email.
> > >
> >
> > Noted, but it does make things easier in some cases (see the Simple
> > example).  However, the design assumes they are separate things.
> >
> > > Shouldn't the WorkspaceInfo logic in DefaultProvider be in
> > > WorkspaceManager?
> > >
> >
> > Possibly; will take another look.
> >
> > - James
> >
> > > - Dan
> > > James M Snell wrote:
> > >> Ok, the server refactoring is coming along very well I think.  Thus
> > >> far, I've been able to greatly simplify the overall design, as well
> > as
> > >> integrate the approaches implemented by Dan and the google
> > feed-server
> > >> team while still maintaining the flexibility of the original
> > framework.
> > >>
> > >> The main components of the refactored design are:
> > >>
> > >>  * AbderaServlet
> > >>  * ServiceContext
> > >>  * Provider
> > >>  * WorkspaceManager
> > >>  * CollectionAdapter
> > >>  * RequestContext
> > >>  * ResponseContext
> > >>  * Target
> > >>  * Resolver<Target>
> > >>  * Resolver<Subject>
> > >>
> > >> For the overwhelming majority of implementations, all an end
> > developer
> > >> will need to do is implement a CollectionAdapter, provide a
> > >> TargetResolver, and glue the two together using a ServiceContext.
> > >>
> > >> The examples in the server_refactor test cases illustrates the three
> > >> fundamental approaches.
> > >>
> > >> The application flow is simple:
> > >>
> > >>  * The AbderaServlet receives a request and creates a ServiceContext
> > >>  * The ServiceContext creates a Provider instance
> > >>  * The Provider instance uses it's associated WorkspaceManager to
> > >>    select a CollectionAdapter.
> > >>  * Once the CollectionAdapter is selected, the Provider forwards the
> > >>    request on to the appropriate method
> > >>
> > >> In some cases, the Provider and the WorkspaceManager will be the same
> >
> > >> object.  In other cases, the Provider and the WorkspaceManager will
> > be
> > >> separate.
> > >>
> > >> Simple
> > >> ------
> > >>
> > >> In the Simple example, the developer implements a CollectionAdapter,
> > a
> > >> Provider and a ServiceContext.
> > >>
> > >> The CollectionAdapter provides the guts of the implementation,
> > >> providing implementations for each of the main prototocol operations
> > >> such as getFeed, getEntry, etc.  These are the methods that used to
> > >> exist on the old style provider interface.
> > >>
> > >> The Provider extends AbstractWorkspaceProvider which means the
> > >> Provider is acting as it's own WorkspaceManager.
> > >>
> > >> The Provider/WorkspaceManager dispatches requests to the
> > SimpleAdapter
> > >> implementation.
> > >>
> > >> The SimpleServiceContext glues the Provider to the appropriate target
> > >> resolver.
> > >>
> > >> Default
> > >> -------
> > >>
> > >> In the Default example, the developer uses the same CollectionAdapter
> > >> implementation used in the simple example but uses the
> > DefaultProvider
> > >> class.
> > >>
> > >> The Default example is similar in nature to the CollectionProvider
> > >> stuff implemented by Dan in that it is the DefaultProvider's job to
> > >> handle things like the creation of the Service document based on
> > >> metadata provided by the developer.
> > >>
> > >> The simple and default examples are nearly identical with the
> > >> exception that the default example supports multiple workspaces and
> > >> collections.
> > >>
> > >> Basic
> > >> -----
> > >>
> > >> The basic example (which is poorly named, I know) is essentially the
> > >> google feed-server stuff, slightly modified so that it sits on top of
> >
> > >> the default provider implementation.
> > >>
> > >> The properties file based deployment is kept intact, but the Adapter
> > >> interface is replaced by the BasicAdapter abstract class, which is an
> >
> > >> abstract CollectionAdapter implementation that defines the same
> > >> abstract methods defined by the google feed-server Adapter interface.
> > >> Existing google feed-server Adapter implementations can be ported to
> > >> this design simply by replacing "implements Adapter" with "extends
> > >> BasicAdapter".
> > >>
> > >> The implementation has been further modified to support the creation
> > >> of a service document.  The code will read all of the *.properties
> > >> files for the adapters and will generate a service document with one
> > >> workspace and one collection per configured adapter.
> > >>
> > >> Service Documents
> > >> -----------------
> > >>
> > >> In this design, the Provider is responsible for serving the service
> > >> documents.  This means that the service document support will vary
> > >> depending on the capabilities of the Provider implementation.
> > >>
> > >> CollectionAdapters
> > >> ------------------
> > >>
> > >> In each of the three approaches, the same CollectionAdapter interface
> >
> > >> is used.  Also, with the possible exception of URI patterns used for
> > >> links, CollectionAdapters should be independent of the Provider
> > >> implementation used.  We need to find a more elegant way of tying
> > >> Target Resolvers and Collection Adapters together while at the same
> > >> time making it easier to manage links, but that can come later.  The
> > >> more important thing is that once a CollectionAdapter is
> > >> implementation, we should be able to use it regardless of which of
> > the
> > >> three models are selected.
> > >>
> > >> Media Collections
> > >> -----------------
> > >>
> > >> The basic CollectionAdapter interface does not support media
> > >> operations.  If you want to implement support for media collections,
> > >> the CollectionAdapter has to implement the MediaCollectionAdapter
> > >> interface.  The reason for this separation is to reduce the
> > complexity
> > >> of the simplest Atompub implementations that will only ever support
> > >> Atom entries.
> > >>
> > >> Transactional
> > >> -------------
> > >>
> > >> CollectionAdapter implementations can implement the Transactional
> > >> interface if they wish to support transactional start/end/compensate
> > >> semantics.  Provider implementations SHOULD call Transactional.start
> > ()
> > >> before delegating to the CollectionAdapter method and
> > >> Transactional.end() after delegating.  If an error occurs, the
> > >> Provider SHOULD call Transactional.compensate().
> > >>
> > >> - James
> > >
> > >
> >
>
>

Re: Feedback round 2 [was Re: Server Refactoring - Overview]

Posted by Stephen Duncan <st...@gmail.com>.
On Jan 23, 2008 2:03 PM, Dan Diephouse <da...@mulesource.com> wrote:
>
>
>
> Some more general coding suggestions:
> * I noticed a lot of the tests have the assertFoo(...) arguments
> reversed. The thing you want the assertion to match should be the first
> argument.


If you want to update to junit 4.4, I've found that switching to using the
assertThat mechanism added in that release prevents these sorts of mistakes,
and has the other benefits listed in the release notes:

http://junit.sourceforge.net/doc/ReleaseNotes4.4.html

(This never seemed to get as much attention as I would have expected when it
was released)

-- 
Stephen Duncan Jr
www.stephenduncanjr.com

Re: Feedback round 2 [was Re: Server Refactoring - Overview]

Posted by James M Snell <ja...@gmail.com>.
Sweet. I'm checking out the complete branch now and will go through it. 
   A bit later today I will add in the Filter stuff.

Before we cut over to this in the trunk, I'd like to take a stab at 
writing up some docs and post a note on the user list to solicit 
feedback on the revised design.

- James

Dan Diephouse wrote:
> OK I'm done for the moment I think. Some outstanding issues/comments:
> 
> * I think things are simplified even more. I removed even more stuff 
> from interfaces and went with a convention over configuration type 
> approach for Providers. You only have to supply the bare minimum amount 
> of information to get a Provider/CollectionAdapter set up now. This can 
> easily be overridden though. Any use case that was supported previously 
> should be supported now.
> * BasicAdapter stuff needs a once over for my changes. James - any 
> chance you can take a look at this? I'm pretty much out of Abdera time 
> for the day. I kind of think BasicAdapter needs a once over anyway.
> * The biggest thing that is still ugly is the resolution. I think the 
> API is fine, but the default implementation may be a little big ugly yet 
> (but it works! :-))
> * If you notice inside the StructuredResolver I do a MimeType check to 
> support POSTing of media collections. If you use the RegexTargetResolver 
> it is currently impossible to do media posts to the same URL as non 
> media entries.
> * I have the JCR test working locally as well, but I need to rebranch 
> the build to include all modules.
> * Do we really need getProperty/getPropertyNames on Provider?
> 
> Some more general coding suggestions:
> * For tests like SimpleTest where we're starting/stopping servers we 
> should use the @BeforeClass/@AfterClass annotations to set up and tear 
> down the server.
> * I noticed a lot of the tests have the assertFoo(...) arguments 
> reversed. The thing you want the assertion to match should be the first 
> argument.
> * The "test" package in the server module is a little redundant.
> * If we refactor in the future we should make sure to do it over the 
> whole build. For instance, it would've been nice if we did a global 
> method rename for createEntry on CollectionProvider to 
> CollectionAdapter.postEntry as it would've saved a bit time. :-)
> 
> Let me know your thoughts.
> Cheers,
> - Dan
> 
> James M Snell wrote:
>> Dan, let me know when you're done with the branch. I've implemented 
>> support for a Filter mechanism that is modeled after the Servlet 
>> Filter design.  It allows a Provider to insert a chain of filters that 
>> are invoked by the AbderaServlet prior to invoking the Provider.  The 
>> initial example I have is an OpenSearchFilter that is capable of 
>> serving up an OpenSearchDescription document and maps Target 
>> parameters to standard OpenSearch query parameters in the RequestContext.
> 
> 

Re: Feedback round 2 [was Re: Server Refactoring - Overview]

Posted by Dan Diephouse <da...@mulesource.com>.
OK I'm done for the moment I think. Some outstanding issues/comments:

* I think things are simplified even more. I removed even more stuff 
from interfaces and went with a convention over configuration type 
approach for Providers. You only have to supply the bare minimum amount 
of information to get a Provider/CollectionAdapter set up now. This can 
easily be overridden though. Any use case that was supported previously 
should be supported now.
* BasicAdapter stuff needs a once over for my changes. James - any 
chance you can take a look at this? I'm pretty much out of Abdera time 
for the day. I kind of think BasicAdapter needs a once over anyway.
* The biggest thing that is still ugly is the resolution. I think the 
API is fine, but the default implementation may be a little big ugly yet 
(but it works! :-))
* If you notice inside the StructuredResolver I do a MimeType check to 
support POSTing of media collections. If you use the RegexTargetResolver 
it is currently impossible to do media posts to the same URL as non 
media entries.
* I have the JCR test working locally as well, but I need to rebranch 
the build to include all modules.
* Do we really need getProperty/getPropertyNames on Provider?

Some more general coding suggestions:
* For tests like SimpleTest where we're starting/stopping servers we 
should use the @BeforeClass/@AfterClass annotations to set up and tear 
down the server.
* I noticed a lot of the tests have the assertFoo(...) arguments 
reversed. The thing you want the assertion to match should be the first 
argument.
* The "test" package in the server module is a little redundant.
* If we refactor in the future we should make sure to do it over the 
whole build. For instance, it would've been nice if we did a global 
method rename for createEntry on CollectionProvider to 
CollectionAdapter.postEntry as it would've saved a bit time. :-)

Let me know your thoughts.
Cheers,
- Dan

James M Snell wrote:
> Dan, let me know when you're done with the branch. I've implemented 
> support for a Filter mechanism that is modeled after the Servlet 
> Filter design.  It allows a Provider to insert a chain of filters that 
> are invoked by the AbderaServlet prior to invoking the Provider.  The 
> initial example I have is an OpenSearchFilter that is capable of 
> serving up an OpenSearchDescription document and maps Target 
> parameters to standard OpenSearch query parameters in the RequestContext.


-- 
Dan Diephouse
MuleSource
http://mulesource.com | http://netzooid.com/blog


Re: Feedback round 2 [was Re: Server Refactoring - Overview]

Posted by James M Snell <ja...@gmail.com>.
Dan, let me know when you're done with the branch. I've implemented 
support for a Filter mechanism that is modeled after the Servlet Filter 
design.  It allows a Provider to insert a chain of filters that are 
invoked by the AbderaServlet prior to invoking the Provider.  The 
initial example I have is an OpenSearchFilter that is capable of serving 
up an OpenSearchDescription document and maps Target parameters to 
standard OpenSearch query parameters in the RequestContext.

- James

Dan Diephouse wrote:
> Heya,
> 
> I have a whole load of changes which I've been working on today mostly 
> trying add back in all the necessary bits and pieces for the 
> AbstractEntityCollectionProvider (Can we please not remove stuff when 
> refactoring in the future? Its a major PITA to add this stuff back in 
> and get the tests passing again). I've also simplified the out of box 
> experience a fair amount by assuming reasonable defaults and allowing 
> users to override them. Anyway, I would appreciate it if the branch was 
> left alone until tomorrow so I can finish up and not have a whole load 
> of conflicts.
> Thanks,
> - Dan
> 
> James M Snell wrote:
>> I'm glad you're happy with things so far.  The code is in 
>> branches/server_refactor and contains a good deal of the feed-server 
>> stuff mostly intact.  A number of important changes were made, such as 
>> the ability to generate a service document listing all of the 
>> *.properties file configured adapters, and the use of the 
>> CollectionAdapter interface and the BasicAdapter abstract class.  For 
>> the most part, however, very little needs to be done to existing 
>> Adapter implementations to get them working in the refactored code.
>>
>> - James
>>
>> Vasu Nori wrote:
>>> James/Dan
>>>
>>> I have just had a chance to look at this email thread about server
>>> refactoring work.
>>> Sounds great. can't wait to see the new code and figure out how google
>>> feedserver code can fit in..
>>>
>>> Is this code in trunk or in some other change-branch?
>>> I got the latest from trunk - but can't find the changes you are talking
>>> about.
>>>
>>> any pointers?
>>>
>>> thanks
>>>
>>> On Jan 22, 2008 8:20 AM, James M Snell <ja...@gmail.com> wrote:
>>>
>>>> Dan Diephouse wrote:
>>>>> Looking good. But even more new comments! Hopefully you aren't sick of
>>>>> me yet :-)
>>>>>
>>>> Never!  Of course, large payments of small unmarked bills would help 
>>>> ;-)
>>>>
>>>>> Can we collapse ServiceContext and Provider? I would propose then that
>>>>> Provider gets getters/setters for Resolver<Subject>/<Target>. If we 
>>>>> did
>>>>> this we could get rid of ServiceContext too I think -- which would
>>>>> remove one more step for the user. I did a similar thing with when I
>>>>> made it implement Resolver<Target>. While I think this should be
>>>>> pluggable, I really think users should not have to configure a 
>>>>> resolver
>>>>> by default.
>>>>>
>>>> Quite possibly. Will take a look today.
>>>>
>>>>> Along these lines I think we should remove the instantiation code 
>>>>> which
>>>>> is in DefaultServiceContext. IMO this is the job of a container of 
>>>>> some
>>>>> sort. I mean container in the broadest sense here.  For instance, I
>>>>> think it could be wrapped up in something like a
>>>>> PropertiesProviderBuilder. It could then configure a whole provider
>>>>> instance - including resolvers, workspace manager, and
>>>> collectionadapters.
>>>> Agreed.
>>>>
>>>>> Transactional.begin/end needs to take RequestContext so I can store a
>>>>> JCR session in it.
>>>>>
>>>> Ok, will add that today.
>>>>
>>>>> The JCR tests provide a good means to test if the basic 
>>>>> ServiceProvider
>>>>> stuff I wrote still roughly works.
>>>>>
>>>> Well, it would need to be ported to the new model as the interfaces 
>>>> have
>>>>  changed.  Would you like to take a stab at that?  Doing so would help
>>>> you get a better feeling for the new design.
>>>>
>>>>> My feeling is that CollectionInfo should not extend CollectionAdapter.
>>>>> While I agree that people will probably implement both CollectionInfo
>>>>> and CollectionAdapter by default, sometimes you want to just return 
>>>>> the
>>>>> metadata.
>>>>>
>>>> Agreed.  CollectionInfo can have a getCollectionAdapter method to
>>>> connect the two.
>>>>
>>>>> Re: BasicAdapter - I'm still unconvinced about this API and its 
>>>>> ability
>>>>> to support the necessary semantics for generic APP stores.
>>>>>
>>>> Ditto.
>>>>
>>>>> CollectionAdapterManager should be in the basic package if we keep the
>>>>> basic stuff around.
>>>>>
>>>> Take another look at CAM; I modified it so that it works generically
>>>> with any CollectionAdapter, not just BasicAdapter.  This would allow 
>>>> any
>>>> Provider implementation to use the properties file deployment mechanism
>>>> independently of whether the BasicAdapter interface is used.
>>>>
>>>>> I get the feeling that
>>>>> WorkspaceManager.checkMethod/checkTarget/getMethods can all 
>>>>> probably go.
>>>>> Could we not work that logic into the 
>>>>> CollectionAdapter.extensionRequest
>>>> ?
>>>> Not sure about this.
>>>>
>>>>> I still don't think its a good idea for a Provider to act as its own
>>>>> WorkspaceManager per my previous email.
>>>>>
>>>> Noted, but it does make things easier in some cases (see the Simple
>>>> example).  However, the design assumes they are separate things.
>>>>
>>>>> Shouldn't the WorkspaceInfo logic in DefaultProvider be in
>>>>> WorkspaceManager?
>>>>>
>>>> Possibly; will take another look.
>>>>
>>>> - James
>>>>
>>>>> - Dan
>>>>> James M Snell wrote:
>>>>>> Ok, the server refactoring is coming along very well I think.  Thus
>>>>>> far, I've been able to greatly simplify the overall design, as 
>>>>>> well as
>>>>>> integrate the approaches implemented by Dan and the google 
>>>>>> feed-server
>>>>>> team while still maintaining the flexibility of the original 
>>>>>> framework.
>>>>>>
>>>>>> The main components of the refactored design are:
>>>>>>
>>>>>>  * AbderaServlet
>>>>>>  * ServiceContext
>>>>>>  * Provider
>>>>>>  * WorkspaceManager
>>>>>>  * CollectionAdapter
>>>>>>  * RequestContext
>>>>>>  * ResponseContext
>>>>>>  * Target
>>>>>>  * Resolver<Target>
>>>>>>  * Resolver<Subject>
>>>>>>
>>>>>> For the overwhelming majority of implementations, all an end 
>>>>>> developer
>>>>>> will need to do is implement a CollectionAdapter, provide a
>>>>>> TargetResolver, and glue the two together using a ServiceContext.
>>>>>>
>>>>>> The examples in the server_refactor test cases illustrates the three
>>>>>> fundamental approaches.
>>>>>>
>>>>>> The application flow is simple:
>>>>>>
>>>>>>  * The AbderaServlet receives a request and creates a ServiceContext
>>>>>>  * The ServiceContext creates a Provider instance
>>>>>>  * The Provider instance uses it's associated WorkspaceManager to
>>>>>>    select a CollectionAdapter.
>>>>>>  * Once the CollectionAdapter is selected, the Provider forwards the
>>>>>>    request on to the appropriate method
>>>>>>
>>>>>> In some cases, the Provider and the WorkspaceManager will be the same
>>>>>> object.  In other cases, the Provider and the WorkspaceManager 
>>>>>> will be
>>>>>> separate.
>>>>>>
>>>>>> Simple
>>>>>> ------
>>>>>>
>>>>>> In the Simple example, the developer implements a 
>>>>>> CollectionAdapter, a
>>>>>> Provider and a ServiceContext.
>>>>>>
>>>>>> The CollectionAdapter provides the guts of the implementation,
>>>>>> providing implementations for each of the main prototocol operations
>>>>>> such as getFeed, getEntry, etc.  These are the methods that used to
>>>>>> exist on the old style provider interface.
>>>>>>
>>>>>> The Provider extends AbstractWorkspaceProvider which means the
>>>>>> Provider is acting as it's own WorkspaceManager.
>>>>>>
>>>>>> The Provider/WorkspaceManager dispatches requests to the 
>>>>>> SimpleAdapter
>>>>>> implementation.
>>>>>>
>>>>>> The SimpleServiceContext glues the Provider to the appropriate target
>>>>>> resolver.
>>>>>>
>>>>>> Default
>>>>>> -------
>>>>>>
>>>>>> In the Default example, the developer uses the same CollectionAdapter
>>>>>> implementation used in the simple example but uses the 
>>>>>> DefaultProvider
>>>>>> class.
>>>>>>
>>>>>> The Default example is similar in nature to the CollectionProvider
>>>>>> stuff implemented by Dan in that it is the DefaultProvider's job to
>>>>>> handle things like the creation of the Service document based on
>>>>>> metadata provided by the developer.
>>>>>>
>>>>>> The simple and default examples are nearly identical with the
>>>>>> exception that the default example supports multiple workspaces and
>>>>>> collections.
>>>>>>
>>>>>> Basic
>>>>>> -----
>>>>>>
>>>>>> The basic example (which is poorly named, I know) is essentially the
>>>>>> google feed-server stuff, slightly modified so that it sits on top of
>>>>>> the default provider implementation.
>>>>>>
>>>>>> The properties file based deployment is kept intact, but the Adapter
>>>>>> interface is replaced by the BasicAdapter abstract class, which is an
>>>>>> abstract CollectionAdapter implementation that defines the same
>>>>>> abstract methods defined by the google feed-server Adapter interface.
>>>>>> Existing google feed-server Adapter implementations can be ported to
>>>>>> this design simply by replacing "implements Adapter" with "extends
>>>>>> BasicAdapter".
>>>>>>
>>>>>> The implementation has been further modified to support the creation
>>>>>> of a service document.  The code will read all of the *.properties
>>>>>> files for the adapters and will generate a service document with one
>>>>>> workspace and one collection per configured adapter.
>>>>>>
>>>>>> Service Documents
>>>>>> -----------------
>>>>>>
>>>>>> In this design, the Provider is responsible for serving the service
>>>>>> documents.  This means that the service document support will vary
>>>>>> depending on the capabilities of the Provider implementation.
>>>>>>
>>>>>> CollectionAdapters
>>>>>> ------------------
>>>>>>
>>>>>> In each of the three approaches, the same CollectionAdapter interface
>>>>>> is used.  Also, with the possible exception of URI patterns used for
>>>>>> links, CollectionAdapters should be independent of the Provider
>>>>>> implementation used.  We need to find a more elegant way of tying
>>>>>> Target Resolvers and Collection Adapters together while at the same
>>>>>> time making it easier to manage links, but that can come later.  The
>>>>>> more important thing is that once a CollectionAdapter is
>>>>>> implementation, we should be able to use it regardless of which of 
>>>>>> the
>>>>>> three models are selected.
>>>>>>
>>>>>> Media Collections
>>>>>> -----------------
>>>>>>
>>>>>> The basic CollectionAdapter interface does not support media
>>>>>> operations.  If you want to implement support for media collections,
>>>>>> the CollectionAdapter has to implement the MediaCollectionAdapter
>>>>>> interface.  The reason for this separation is to reduce the 
>>>>>> complexity
>>>>>> of the simplest Atompub implementations that will only ever support
>>>>>> Atom entries.
>>>>>>
>>>>>> Transactional
>>>>>> -------------
>>>>>>
>>>>>> CollectionAdapter implementations can implement the Transactional
>>>>>> interface if they wish to support transactional start/end/compensate
>>>>>> semantics.  Provider implementations SHOULD call 
>>>>>> Transactional.start()
>>>>>> before delegating to the CollectionAdapter method and
>>>>>> Transactional.end() after delegating.  If an error occurs, the
>>>>>> Provider SHOULD call Transactional.compensate().
>>>>>>
>>>>>> - James
>>>>>
>>>
> 
> 

Re: Feedback round 2 [was Re: Server Refactoring - Overview]

Posted by Dan Diephouse <da...@mulesource.com>.
James M Snell wrote:
> Heh, don't feel bad, it's definitely nothing personal :-). you should 
> see the number of compile errors I had in my code today when I 
> switched it over to the new stuff.  I'll be working the rest of the 
> week to get it all sorted out.  This is why all of the work was done 
> in a branch. All of the AbstractEntityCollectionProvider stuff is 
> still there in the trunk.  I would have ported it over myself during 
> the refactoring but I'm nowhere near as familiar with that code as you 
> are and would only have been guessing as to how best to port it.  So, 
> I apologize for causing you some headaches, but hopefully, in the long 
> run, the changes will be for the better.  I, for one, am certainly 
> quite happy with the refactoring and I appreciate the feedback you've 
> been providing.
Yeah, I've been there myself. I guess I just meant that instead of 
deleting/redoing things whole sale it would've been better to just 
rename CollectionProvider to CollectionAdapter for instance or removing 
some of the redundant arguments on CP using Eclipse's refactoring tools 
so all the tests still compiled/stayed in tact. Then I could go over 
them later, but not have to worry too much about the details like adding 
back in the necessary semantics to Transactional and what not. No hard 
feelings, but it just would've made our lives a bit easier I think.
Cheers,
- Dan

-- 
Dan Diephouse
MuleSource
http://mulesource.com | http://netzooid.com/blog


Re: Feedback round 2 [was Re: Server Refactoring - Overview]

Posted by James M Snell <ja...@gmail.com>.
Heh, don't feel bad, it's definitely nothing personal :-). you should 
see the number of compile errors I had in my code today when I switched 
it over to the new stuff.  I'll be working the rest of the week to get 
it all sorted out.  This is why all of the work was done in a branch. 
All of the AbstractEntityCollectionProvider stuff is still there in the 
trunk.  I would have ported it over myself during the refactoring but 
I'm nowhere near as familiar with that code as you are and would only 
have been guessing as to how best to port it.  So, I apologize for 
causing you some headaches, but hopefully, in the long run, the changes 
will be for the better.  I, for one, am certainly quite happy with the 
refactoring and I appreciate the feedback you've been providing.

- James

Dan Diephouse wrote:
> Heya,
> 
> I have a whole load of changes which I've been working on today mostly 
> trying add back in all the necessary bits and pieces for the 
> AbstractEntityCollectionProvider (Can we please not remove stuff when 
> refactoring in the future? Its a major PITA to add this stuff back in 
> and get the tests passing again). I've also simplified the out of box 
> experience a fair amount by assuming reasonable defaults and allowing 
> users to override them. Anyway, I would appreciate it if the branch was 
> left alone until tomorrow so I can finish up and not have a whole load 
> of conflicts.
> Thanks,
> - Dan
> 
> James M Snell wrote:
>> I'm glad you're happy with things so far.  The code is in 
>> branches/server_refactor and contains a good deal of the feed-server 
>> stuff mostly intact.  A number of important changes were made, such as 
>> the ability to generate a service document listing all of the 
>> *.properties file configured adapters, and the use of the 
>> CollectionAdapter interface and the BasicAdapter abstract class.  For 
>> the most part, however, very little needs to be done to existing 
>> Adapter implementations to get them working in the refactored code.
>>
>> - James
>>
>> Vasu Nori wrote:
>>> James/Dan
>>>
>>> I have just had a chance to look at this email thread about server
>>> refactoring work.
>>> Sounds great. can't wait to see the new code and figure out how google
>>> feedserver code can fit in..
>>>
>>> Is this code in trunk or in some other change-branch?
>>> I got the latest from trunk - but can't find the changes you are talking
>>> about.
>>>
>>> any pointers?
>>>
>>> thanks
>>>
>>> On Jan 22, 2008 8:20 AM, James M Snell <ja...@gmail.com> wrote:
>>>
>>>> Dan Diephouse wrote:
>>>>> Looking good. But even more new comments! Hopefully you aren't sick of
>>>>> me yet :-)
>>>>>
>>>> Never!  Of course, large payments of small unmarked bills would help 
>>>> ;-)
>>>>
>>>>> Can we collapse ServiceContext and Provider? I would propose then that
>>>>> Provider gets getters/setters for Resolver<Subject>/<Target>. If we 
>>>>> did
>>>>> this we could get rid of ServiceContext too I think -- which would
>>>>> remove one more step for the user. I did a similar thing with when I
>>>>> made it implement Resolver<Target>. While I think this should be
>>>>> pluggable, I really think users should not have to configure a 
>>>>> resolver
>>>>> by default.
>>>>>
>>>> Quite possibly. Will take a look today.
>>>>
>>>>> Along these lines I think we should remove the instantiation code 
>>>>> which
>>>>> is in DefaultServiceContext. IMO this is the job of a container of 
>>>>> some
>>>>> sort. I mean container in the broadest sense here.  For instance, I
>>>>> think it could be wrapped up in something like a
>>>>> PropertiesProviderBuilder. It could then configure a whole provider
>>>>> instance - including resolvers, workspace manager, and
>>>> collectionadapters.
>>>> Agreed.
>>>>
>>>>> Transactional.begin/end needs to take RequestContext so I can store a
>>>>> JCR session in it.
>>>>>
>>>> Ok, will add that today.
>>>>
>>>>> The JCR tests provide a good means to test if the basic 
>>>>> ServiceProvider
>>>>> stuff I wrote still roughly works.
>>>>>
>>>> Well, it would need to be ported to the new model as the interfaces 
>>>> have
>>>>  changed.  Would you like to take a stab at that?  Doing so would help
>>>> you get a better feeling for the new design.
>>>>
>>>>> My feeling is that CollectionInfo should not extend CollectionAdapter.
>>>>> While I agree that people will probably implement both CollectionInfo
>>>>> and CollectionAdapter by default, sometimes you want to just return 
>>>>> the
>>>>> metadata.
>>>>>
>>>> Agreed.  CollectionInfo can have a getCollectionAdapter method to
>>>> connect the two.
>>>>
>>>>> Re: BasicAdapter - I'm still unconvinced about this API and its 
>>>>> ability
>>>>> to support the necessary semantics for generic APP stores.
>>>>>
>>>> Ditto.
>>>>
>>>>> CollectionAdapterManager should be in the basic package if we keep the
>>>>> basic stuff around.
>>>>>
>>>> Take another look at CAM; I modified it so that it works generically
>>>> with any CollectionAdapter, not just BasicAdapter.  This would allow 
>>>> any
>>>> Provider implementation to use the properties file deployment mechanism
>>>> independently of whether the BasicAdapter interface is used.
>>>>
>>>>> I get the feeling that
>>>>> WorkspaceManager.checkMethod/checkTarget/getMethods can all 
>>>>> probably go.
>>>>> Could we not work that logic into the 
>>>>> CollectionAdapter.extensionRequest
>>>> ?
>>>> Not sure about this.
>>>>
>>>>> I still don't think its a good idea for a Provider to act as its own
>>>>> WorkspaceManager per my previous email.
>>>>>
>>>> Noted, but it does make things easier in some cases (see the Simple
>>>> example).  However, the design assumes they are separate things.
>>>>
>>>>> Shouldn't the WorkspaceInfo logic in DefaultProvider be in
>>>>> WorkspaceManager?
>>>>>
>>>> Possibly; will take another look.
>>>>
>>>> - James
>>>>
>>>>> - Dan
>>>>> James M Snell wrote:
>>>>>> Ok, the server refactoring is coming along very well I think.  Thus
>>>>>> far, I've been able to greatly simplify the overall design, as 
>>>>>> well as
>>>>>> integrate the approaches implemented by Dan and the google 
>>>>>> feed-server
>>>>>> team while still maintaining the flexibility of the original 
>>>>>> framework.
>>>>>>
>>>>>> The main components of the refactored design are:
>>>>>>
>>>>>>  * AbderaServlet
>>>>>>  * ServiceContext
>>>>>>  * Provider
>>>>>>  * WorkspaceManager
>>>>>>  * CollectionAdapter
>>>>>>  * RequestContext
>>>>>>  * ResponseContext
>>>>>>  * Target
>>>>>>  * Resolver<Target>
>>>>>>  * Resolver<Subject>
>>>>>>
>>>>>> For the overwhelming majority of implementations, all an end 
>>>>>> developer
>>>>>> will need to do is implement a CollectionAdapter, provide a
>>>>>> TargetResolver, and glue the two together using a ServiceContext.
>>>>>>
>>>>>> The examples in the server_refactor test cases illustrates the three
>>>>>> fundamental approaches.
>>>>>>
>>>>>> The application flow is simple:
>>>>>>
>>>>>>  * The AbderaServlet receives a request and creates a ServiceContext
>>>>>>  * The ServiceContext creates a Provider instance
>>>>>>  * The Provider instance uses it's associated WorkspaceManager to
>>>>>>    select a CollectionAdapter.
>>>>>>  * Once the CollectionAdapter is selected, the Provider forwards the
>>>>>>    request on to the appropriate method
>>>>>>
>>>>>> In some cases, the Provider and the WorkspaceManager will be the same
>>>>>> object.  In other cases, the Provider and the WorkspaceManager 
>>>>>> will be
>>>>>> separate.
>>>>>>
>>>>>> Simple
>>>>>> ------
>>>>>>
>>>>>> In the Simple example, the developer implements a 
>>>>>> CollectionAdapter, a
>>>>>> Provider and a ServiceContext.
>>>>>>
>>>>>> The CollectionAdapter provides the guts of the implementation,
>>>>>> providing implementations for each of the main prototocol operations
>>>>>> such as getFeed, getEntry, etc.  These are the methods that used to
>>>>>> exist on the old style provider interface.
>>>>>>
>>>>>> The Provider extends AbstractWorkspaceProvider which means the
>>>>>> Provider is acting as it's own WorkspaceManager.
>>>>>>
>>>>>> The Provider/WorkspaceManager dispatches requests to the 
>>>>>> SimpleAdapter
>>>>>> implementation.
>>>>>>
>>>>>> The SimpleServiceContext glues the Provider to the appropriate target
>>>>>> resolver.
>>>>>>
>>>>>> Default
>>>>>> -------
>>>>>>
>>>>>> In the Default example, the developer uses the same CollectionAdapter
>>>>>> implementation used in the simple example but uses the 
>>>>>> DefaultProvider
>>>>>> class.
>>>>>>
>>>>>> The Default example is similar in nature to the CollectionProvider
>>>>>> stuff implemented by Dan in that it is the DefaultProvider's job to
>>>>>> handle things like the creation of the Service document based on
>>>>>> metadata provided by the developer.
>>>>>>
>>>>>> The simple and default examples are nearly identical with the
>>>>>> exception that the default example supports multiple workspaces and
>>>>>> collections.
>>>>>>
>>>>>> Basic
>>>>>> -----
>>>>>>
>>>>>> The basic example (which is poorly named, I know) is essentially the
>>>>>> google feed-server stuff, slightly modified so that it sits on top of
>>>>>> the default provider implementation.
>>>>>>
>>>>>> The properties file based deployment is kept intact, but the Adapter
>>>>>> interface is replaced by the BasicAdapter abstract class, which is an
>>>>>> abstract CollectionAdapter implementation that defines the same
>>>>>> abstract methods defined by the google feed-server Adapter interface.
>>>>>> Existing google feed-server Adapter implementations can be ported to
>>>>>> this design simply by replacing "implements Adapter" with "extends
>>>>>> BasicAdapter".
>>>>>>
>>>>>> The implementation has been further modified to support the creation
>>>>>> of a service document.  The code will read all of the *.properties
>>>>>> files for the adapters and will generate a service document with one
>>>>>> workspace and one collection per configured adapter.
>>>>>>
>>>>>> Service Documents
>>>>>> -----------------
>>>>>>
>>>>>> In this design, the Provider is responsible for serving the service
>>>>>> documents.  This means that the service document support will vary
>>>>>> depending on the capabilities of the Provider implementation.
>>>>>>
>>>>>> CollectionAdapters
>>>>>> ------------------
>>>>>>
>>>>>> In each of the three approaches, the same CollectionAdapter interface
>>>>>> is used.  Also, with the possible exception of URI patterns used for
>>>>>> links, CollectionAdapters should be independent of the Provider
>>>>>> implementation used.  We need to find a more elegant way of tying
>>>>>> Target Resolvers and Collection Adapters together while at the same
>>>>>> time making it easier to manage links, but that can come later.  The
>>>>>> more important thing is that once a CollectionAdapter is
>>>>>> implementation, we should be able to use it regardless of which of 
>>>>>> the
>>>>>> three models are selected.
>>>>>>
>>>>>> Media Collections
>>>>>> -----------------
>>>>>>
>>>>>> The basic CollectionAdapter interface does not support media
>>>>>> operations.  If you want to implement support for media collections,
>>>>>> the CollectionAdapter has to implement the MediaCollectionAdapter
>>>>>> interface.  The reason for this separation is to reduce the 
>>>>>> complexity
>>>>>> of the simplest Atompub implementations that will only ever support
>>>>>> Atom entries.
>>>>>>
>>>>>> Transactional
>>>>>> -------------
>>>>>>
>>>>>> CollectionAdapter implementations can implement the Transactional
>>>>>> interface if they wish to support transactional start/end/compensate
>>>>>> semantics.  Provider implementations SHOULD call 
>>>>>> Transactional.start()
>>>>>> before delegating to the CollectionAdapter method and
>>>>>> Transactional.end() after delegating.  If an error occurs, the
>>>>>> Provider SHOULD call Transactional.compensate().
>>>>>>
>>>>>> - James
>>>>>
>>>
> 
> 

Re: Feedback round 2 [was Re: Server Refactoring - Overview]

Posted by Dan Diephouse <da...@mulesource.com>.
Heya,

I have a whole load of changes which I've been working on today mostly 
trying add back in all the necessary bits and pieces for the 
AbstractEntityCollectionProvider (Can we please not remove stuff when 
refactoring in the future? Its a major PITA to add this stuff back in 
and get the tests passing again). I've also simplified the out of box 
experience a fair amount by assuming reasonable defaults and allowing 
users to override them. Anyway, I would appreciate it if the branch was 
left alone until tomorrow so I can finish up and not have a whole load 
of conflicts.
Thanks,
- Dan

James M Snell wrote:
> I'm glad you're happy with things so far.  The code is in 
> branches/server_refactor and contains a good deal of the feed-server 
> stuff mostly intact.  A number of important changes were made, such as 
> the ability to generate a service document listing all of the 
> *.properties file configured adapters, and the use of the 
> CollectionAdapter interface and the BasicAdapter abstract class.  For 
> the most part, however, very little needs to be done to existing 
> Adapter implementations to get them working in the refactored code.
>
> - James
>
> Vasu Nori wrote:
>> James/Dan
>>
>> I have just had a chance to look at this email thread about server
>> refactoring work.
>> Sounds great. can't wait to see the new code and figure out how google
>> feedserver code can fit in..
>>
>> Is this code in trunk or in some other change-branch?
>> I got the latest from trunk - but can't find the changes you are talking
>> about.
>>
>> any pointers?
>>
>> thanks
>>
>> On Jan 22, 2008 8:20 AM, James M Snell <ja...@gmail.com> wrote:
>>
>>> Dan Diephouse wrote:
>>>> Looking good. But even more new comments! Hopefully you aren't sick of
>>>> me yet :-)
>>>>
>>> Never!  Of course, large payments of small unmarked bills would help 
>>> ;-)
>>>
>>>> Can we collapse ServiceContext and Provider? I would propose then that
>>>> Provider gets getters/setters for Resolver<Subject>/<Target>. If we 
>>>> did
>>>> this we could get rid of ServiceContext too I think -- which would
>>>> remove one more step for the user. I did a similar thing with when I
>>>> made it implement Resolver<Target>. While I think this should be
>>>> pluggable, I really think users should not have to configure a 
>>>> resolver
>>>> by default.
>>>>
>>> Quite possibly. Will take a look today.
>>>
>>>> Along these lines I think we should remove the instantiation code 
>>>> which
>>>> is in DefaultServiceContext. IMO this is the job of a container of 
>>>> some
>>>> sort. I mean container in the broadest sense here.  For instance, I
>>>> think it could be wrapped up in something like a
>>>> PropertiesProviderBuilder. It could then configure a whole provider
>>>> instance - including resolvers, workspace manager, and
>>> collectionadapters.
>>> Agreed.
>>>
>>>> Transactional.begin/end needs to take RequestContext so I can store a
>>>> JCR session in it.
>>>>
>>> Ok, will add that today.
>>>
>>>> The JCR tests provide a good means to test if the basic 
>>>> ServiceProvider
>>>> stuff I wrote still roughly works.
>>>>
>>> Well, it would need to be ported to the new model as the interfaces 
>>> have
>>>  changed.  Would you like to take a stab at that?  Doing so would help
>>> you get a better feeling for the new design.
>>>
>>>> My feeling is that CollectionInfo should not extend CollectionAdapter.
>>>> While I agree that people will probably implement both CollectionInfo
>>>> and CollectionAdapter by default, sometimes you want to just return 
>>>> the
>>>> metadata.
>>>>
>>> Agreed.  CollectionInfo can have a getCollectionAdapter method to
>>> connect the two.
>>>
>>>> Re: BasicAdapter - I'm still unconvinced about this API and its 
>>>> ability
>>>> to support the necessary semantics for generic APP stores.
>>>>
>>> Ditto.
>>>
>>>> CollectionAdapterManager should be in the basic package if we keep the
>>>> basic stuff around.
>>>>
>>> Take another look at CAM; I modified it so that it works generically
>>> with any CollectionAdapter, not just BasicAdapter.  This would allow 
>>> any
>>> Provider implementation to use the properties file deployment mechanism
>>> independently of whether the BasicAdapter interface is used.
>>>
>>>> I get the feeling that
>>>> WorkspaceManager.checkMethod/checkTarget/getMethods can all 
>>>> probably go.
>>>> Could we not work that logic into the 
>>>> CollectionAdapter.extensionRequest
>>> ?
>>> Not sure about this.
>>>
>>>> I still don't think its a good idea for a Provider to act as its own
>>>> WorkspaceManager per my previous email.
>>>>
>>> Noted, but it does make things easier in some cases (see the Simple
>>> example).  However, the design assumes they are separate things.
>>>
>>>> Shouldn't the WorkspaceInfo logic in DefaultProvider be in
>>>> WorkspaceManager?
>>>>
>>> Possibly; will take another look.
>>>
>>> - James
>>>
>>>> - Dan
>>>> James M Snell wrote:
>>>>> Ok, the server refactoring is coming along very well I think.  Thus
>>>>> far, I've been able to greatly simplify the overall design, as 
>>>>> well as
>>>>> integrate the approaches implemented by Dan and the google 
>>>>> feed-server
>>>>> team while still maintaining the flexibility of the original 
>>>>> framework.
>>>>>
>>>>> The main components of the refactored design are:
>>>>>
>>>>>  * AbderaServlet
>>>>>  * ServiceContext
>>>>>  * Provider
>>>>>  * WorkspaceManager
>>>>>  * CollectionAdapter
>>>>>  * RequestContext
>>>>>  * ResponseContext
>>>>>  * Target
>>>>>  * Resolver<Target>
>>>>>  * Resolver<Subject>
>>>>>
>>>>> For the overwhelming majority of implementations, all an end 
>>>>> developer
>>>>> will need to do is implement a CollectionAdapter, provide a
>>>>> TargetResolver, and glue the two together using a ServiceContext.
>>>>>
>>>>> The examples in the server_refactor test cases illustrates the three
>>>>> fundamental approaches.
>>>>>
>>>>> The application flow is simple:
>>>>>
>>>>>  * The AbderaServlet receives a request and creates a ServiceContext
>>>>>  * The ServiceContext creates a Provider instance
>>>>>  * The Provider instance uses it's associated WorkspaceManager to
>>>>>    select a CollectionAdapter.
>>>>>  * Once the CollectionAdapter is selected, the Provider forwards the
>>>>>    request on to the appropriate method
>>>>>
>>>>> In some cases, the Provider and the WorkspaceManager will be the same
>>>>> object.  In other cases, the Provider and the WorkspaceManager 
>>>>> will be
>>>>> separate.
>>>>>
>>>>> Simple
>>>>> ------
>>>>>
>>>>> In the Simple example, the developer implements a 
>>>>> CollectionAdapter, a
>>>>> Provider and a ServiceContext.
>>>>>
>>>>> The CollectionAdapter provides the guts of the implementation,
>>>>> providing implementations for each of the main prototocol operations
>>>>> such as getFeed, getEntry, etc.  These are the methods that used to
>>>>> exist on the old style provider interface.
>>>>>
>>>>> The Provider extends AbstractWorkspaceProvider which means the
>>>>> Provider is acting as it's own WorkspaceManager.
>>>>>
>>>>> The Provider/WorkspaceManager dispatches requests to the 
>>>>> SimpleAdapter
>>>>> implementation.
>>>>>
>>>>> The SimpleServiceContext glues the Provider to the appropriate target
>>>>> resolver.
>>>>>
>>>>> Default
>>>>> -------
>>>>>
>>>>> In the Default example, the developer uses the same CollectionAdapter
>>>>> implementation used in the simple example but uses the 
>>>>> DefaultProvider
>>>>> class.
>>>>>
>>>>> The Default example is similar in nature to the CollectionProvider
>>>>> stuff implemented by Dan in that it is the DefaultProvider's job to
>>>>> handle things like the creation of the Service document based on
>>>>> metadata provided by the developer.
>>>>>
>>>>> The simple and default examples are nearly identical with the
>>>>> exception that the default example supports multiple workspaces and
>>>>> collections.
>>>>>
>>>>> Basic
>>>>> -----
>>>>>
>>>>> The basic example (which is poorly named, I know) is essentially the
>>>>> google feed-server stuff, slightly modified so that it sits on top of
>>>>> the default provider implementation.
>>>>>
>>>>> The properties file based deployment is kept intact, but the Adapter
>>>>> interface is replaced by the BasicAdapter abstract class, which is an
>>>>> abstract CollectionAdapter implementation that defines the same
>>>>> abstract methods defined by the google feed-server Adapter interface.
>>>>> Existing google feed-server Adapter implementations can be ported to
>>>>> this design simply by replacing "implements Adapter" with "extends
>>>>> BasicAdapter".
>>>>>
>>>>> The implementation has been further modified to support the creation
>>>>> of a service document.  The code will read all of the *.properties
>>>>> files for the adapters and will generate a service document with one
>>>>> workspace and one collection per configured adapter.
>>>>>
>>>>> Service Documents
>>>>> -----------------
>>>>>
>>>>> In this design, the Provider is responsible for serving the service
>>>>> documents.  This means that the service document support will vary
>>>>> depending on the capabilities of the Provider implementation.
>>>>>
>>>>> CollectionAdapters
>>>>> ------------------
>>>>>
>>>>> In each of the three approaches, the same CollectionAdapter interface
>>>>> is used.  Also, with the possible exception of URI patterns used for
>>>>> links, CollectionAdapters should be independent of the Provider
>>>>> implementation used.  We need to find a more elegant way of tying
>>>>> Target Resolvers and Collection Adapters together while at the same
>>>>> time making it easier to manage links, but that can come later.  The
>>>>> more important thing is that once a CollectionAdapter is
>>>>> implementation, we should be able to use it regardless of which of 
>>>>> the
>>>>> three models are selected.
>>>>>
>>>>> Media Collections
>>>>> -----------------
>>>>>
>>>>> The basic CollectionAdapter interface does not support media
>>>>> operations.  If you want to implement support for media collections,
>>>>> the CollectionAdapter has to implement the MediaCollectionAdapter
>>>>> interface.  The reason for this separation is to reduce the 
>>>>> complexity
>>>>> of the simplest Atompub implementations that will only ever support
>>>>> Atom entries.
>>>>>
>>>>> Transactional
>>>>> -------------
>>>>>
>>>>> CollectionAdapter implementations can implement the Transactional
>>>>> interface if they wish to support transactional start/end/compensate
>>>>> semantics.  Provider implementations SHOULD call 
>>>>> Transactional.start()
>>>>> before delegating to the CollectionAdapter method and
>>>>> Transactional.end() after delegating.  If an error occurs, the
>>>>> Provider SHOULD call Transactional.compensate().
>>>>>
>>>>> - James
>>>>
>>


-- 
Dan Diephouse
MuleSource
http://mulesource.com | http://netzooid.com/blog


Re: Feedback round 2 [was Re: Server Refactoring - Overview]

Posted by James M Snell <ja...@gmail.com>.
I'm glad you're happy with things so far.  The code is in 
branches/server_refactor and contains a good deal of the feed-server 
stuff mostly intact.  A number of important changes were made, such as 
the ability to generate a service document listing all of the 
*.properties file configured adapters, and the use of the 
CollectionAdapter interface and the BasicAdapter abstract class.  For 
the most part, however, very little needs to be done to existing Adapter 
implementations to get them working in the refactored code.

- James

Vasu Nori wrote:
> James/Dan
> 
> I have just had a chance to look at this email thread about server
> refactoring work.
> Sounds great. can't wait to see the new code and figure out how google
> feedserver code can fit in..
> 
> Is this code in trunk or in some other change-branch?
> I got the latest from trunk - but can't find the changes you are talking
> about.
> 
> any pointers?
> 
> thanks
> 
> On Jan 22, 2008 8:20 AM, James M Snell <ja...@gmail.com> wrote:
> 
>> Dan Diephouse wrote:
>>> Looking good. But even more new comments! Hopefully you aren't sick of
>>> me yet :-)
>>>
>> Never!  Of course, large payments of small unmarked bills would help ;-)
>>
>>> Can we collapse ServiceContext and Provider? I would propose then that
>>> Provider gets getters/setters for Resolver<Subject>/<Target>. If we did
>>> this we could get rid of ServiceContext too I think -- which would
>>> remove one more step for the user. I did a similar thing with when I
>>> made it implement Resolver<Target>. While I think this should be
>>> pluggable, I really think users should not have to configure a resolver
>>> by default.
>>>
>> Quite possibly. Will take a look today.
>>
>>> Along these lines I think we should remove the instantiation code which
>>> is in DefaultServiceContext. IMO this is the job of a container of some
>>> sort. I mean container in the broadest sense here.  For instance, I
>>> think it could be wrapped up in something like a
>>> PropertiesProviderBuilder. It could then configure a whole provider
>>> instance - including resolvers, workspace manager, and
>> collectionadapters.
>> Agreed.
>>
>>> Transactional.begin/end needs to take RequestContext so I can store a
>>> JCR session in it.
>>>
>> Ok, will add that today.
>>
>>> The JCR tests provide a good means to test if the basic ServiceProvider
>>> stuff I wrote still roughly works.
>>>
>> Well, it would need to be ported to the new model as the interfaces have
>>  changed.  Would you like to take a stab at that?  Doing so would help
>> you get a better feeling for the new design.
>>
>>> My feeling is that CollectionInfo should not extend CollectionAdapter.
>>> While I agree that people will probably implement both CollectionInfo
>>> and CollectionAdapter by default, sometimes you want to just return the
>>> metadata.
>>>
>> Agreed.  CollectionInfo can have a getCollectionAdapter method to
>> connect the two.
>>
>>> Re: BasicAdapter - I'm still unconvinced about this API and its ability
>>> to support the necessary semantics for generic APP stores.
>>>
>> Ditto.
>>
>>> CollectionAdapterManager should be in the basic package if we keep the
>>> basic stuff around.
>>>
>> Take another look at CAM; I modified it so that it works generically
>> with any CollectionAdapter, not just BasicAdapter.  This would allow any
>> Provider implementation to use the properties file deployment mechanism
>> independently of whether the BasicAdapter interface is used.
>>
>>> I get the feeling that
>>> WorkspaceManager.checkMethod/checkTarget/getMethods can all probably go.
>>> Could we not work that logic into the CollectionAdapter.extensionRequest
>> ?
>> Not sure about this.
>>
>>> I still don't think its a good idea for a Provider to act as its own
>>> WorkspaceManager per my previous email.
>>>
>> Noted, but it does make things easier in some cases (see the Simple
>> example).  However, the design assumes they are separate things.
>>
>>> Shouldn't the WorkspaceInfo logic in DefaultProvider be in
>>> WorkspaceManager?
>>>
>> Possibly; will take another look.
>>
>> - James
>>
>>> - Dan
>>> James M Snell wrote:
>>>> Ok, the server refactoring is coming along very well I think.  Thus
>>>> far, I've been able to greatly simplify the overall design, as well as
>>>> integrate the approaches implemented by Dan and the google feed-server
>>>> team while still maintaining the flexibility of the original framework.
>>>>
>>>> The main components of the refactored design are:
>>>>
>>>>  * AbderaServlet
>>>>  * ServiceContext
>>>>  * Provider
>>>>  * WorkspaceManager
>>>>  * CollectionAdapter
>>>>  * RequestContext
>>>>  * ResponseContext
>>>>  * Target
>>>>  * Resolver<Target>
>>>>  * Resolver<Subject>
>>>>
>>>> For the overwhelming majority of implementations, all an end developer
>>>> will need to do is implement a CollectionAdapter, provide a
>>>> TargetResolver, and glue the two together using a ServiceContext.
>>>>
>>>> The examples in the server_refactor test cases illustrates the three
>>>> fundamental approaches.
>>>>
>>>> The application flow is simple:
>>>>
>>>>  * The AbderaServlet receives a request and creates a ServiceContext
>>>>  * The ServiceContext creates a Provider instance
>>>>  * The Provider instance uses it's associated WorkspaceManager to
>>>>    select a CollectionAdapter.
>>>>  * Once the CollectionAdapter is selected, the Provider forwards the
>>>>    request on to the appropriate method
>>>>
>>>> In some cases, the Provider and the WorkspaceManager will be the same
>>>> object.  In other cases, the Provider and the WorkspaceManager will be
>>>> separate.
>>>>
>>>> Simple
>>>> ------
>>>>
>>>> In the Simple example, the developer implements a CollectionAdapter, a
>>>> Provider and a ServiceContext.
>>>>
>>>> The CollectionAdapter provides the guts of the implementation,
>>>> providing implementations for each of the main prototocol operations
>>>> such as getFeed, getEntry, etc.  These are the methods that used to
>>>> exist on the old style provider interface.
>>>>
>>>> The Provider extends AbstractWorkspaceProvider which means the
>>>> Provider is acting as it's own WorkspaceManager.
>>>>
>>>> The Provider/WorkspaceManager dispatches requests to the SimpleAdapter
>>>> implementation.
>>>>
>>>> The SimpleServiceContext glues the Provider to the appropriate target
>>>> resolver.
>>>>
>>>> Default
>>>> -------
>>>>
>>>> In the Default example, the developer uses the same CollectionAdapter
>>>> implementation used in the simple example but uses the DefaultProvider
>>>> class.
>>>>
>>>> The Default example is similar in nature to the CollectionProvider
>>>> stuff implemented by Dan in that it is the DefaultProvider's job to
>>>> handle things like the creation of the Service document based on
>>>> metadata provided by the developer.
>>>>
>>>> The simple and default examples are nearly identical with the
>>>> exception that the default example supports multiple workspaces and
>>>> collections.
>>>>
>>>> Basic
>>>> -----
>>>>
>>>> The basic example (which is poorly named, I know) is essentially the
>>>> google feed-server stuff, slightly modified so that it sits on top of
>>>> the default provider implementation.
>>>>
>>>> The properties file based deployment is kept intact, but the Adapter
>>>> interface is replaced by the BasicAdapter abstract class, which is an
>>>> abstract CollectionAdapter implementation that defines the same
>>>> abstract methods defined by the google feed-server Adapter interface.
>>>> Existing google feed-server Adapter implementations can be ported to
>>>> this design simply by replacing "implements Adapter" with "extends
>>>> BasicAdapter".
>>>>
>>>> The implementation has been further modified to support the creation
>>>> of a service document.  The code will read all of the *.properties
>>>> files for the adapters and will generate a service document with one
>>>> workspace and one collection per configured adapter.
>>>>
>>>> Service Documents
>>>> -----------------
>>>>
>>>> In this design, the Provider is responsible for serving the service
>>>> documents.  This means that the service document support will vary
>>>> depending on the capabilities of the Provider implementation.
>>>>
>>>> CollectionAdapters
>>>> ------------------
>>>>
>>>> In each of the three approaches, the same CollectionAdapter interface
>>>> is used.  Also, with the possible exception of URI patterns used for
>>>> links, CollectionAdapters should be independent of the Provider
>>>> implementation used.  We need to find a more elegant way of tying
>>>> Target Resolvers and Collection Adapters together while at the same
>>>> time making it easier to manage links, but that can come later.  The
>>>> more important thing is that once a CollectionAdapter is
>>>> implementation, we should be able to use it regardless of which of the
>>>> three models are selected.
>>>>
>>>> Media Collections
>>>> -----------------
>>>>
>>>> The basic CollectionAdapter interface does not support media
>>>> operations.  If you want to implement support for media collections,
>>>> the CollectionAdapter has to implement the MediaCollectionAdapter
>>>> interface.  The reason for this separation is to reduce the complexity
>>>> of the simplest Atompub implementations that will only ever support
>>>> Atom entries.
>>>>
>>>> Transactional
>>>> -------------
>>>>
>>>> CollectionAdapter implementations can implement the Transactional
>>>> interface if they wish to support transactional start/end/compensate
>>>> semantics.  Provider implementations SHOULD call Transactional.start()
>>>> before delegating to the CollectionAdapter method and
>>>> Transactional.end() after delegating.  If an error occurs, the
>>>> Provider SHOULD call Transactional.compensate().
>>>>
>>>> - James
>>>
> 

Re: Feedback round 2 [was Re: Server Refactoring - Overview]

Posted by Vasu Nori <va...@gmail.com>.
James/Dan

I have just had a chance to look at this email thread about server
refactoring work.
Sounds great. can't wait to see the new code and figure out how google
feedserver code can fit in..

Is this code in trunk or in some other change-branch?
I got the latest from trunk - but can't find the changes you are talking
about.

any pointers?

thanks

On Jan 22, 2008 8:20 AM, James M Snell <ja...@gmail.com> wrote:

>
> Dan Diephouse wrote:
> > Looking good. But even more new comments! Hopefully you aren't sick of
> > me yet :-)
> >
>
> Never!  Of course, large payments of small unmarked bills would help ;-)
>
> > Can we collapse ServiceContext and Provider? I would propose then that
> > Provider gets getters/setters for Resolver<Subject>/<Target>. If we did
> > this we could get rid of ServiceContext too I think -- which would
> > remove one more step for the user. I did a similar thing with when I
> > made it implement Resolver<Target>. While I think this should be
> > pluggable, I really think users should not have to configure a resolver
> > by default.
> >
>
> Quite possibly. Will take a look today.
>
> > Along these lines I think we should remove the instantiation code which
> > is in DefaultServiceContext. IMO this is the job of a container of some
> > sort. I mean container in the broadest sense here.  For instance, I
> > think it could be wrapped up in something like a
> > PropertiesProviderBuilder. It could then configure a whole provider
> > instance - including resolvers, workspace manager, and
> collectionadapters.
> >
>
> Agreed.
>
> > Transactional.begin/end needs to take RequestContext so I can store a
> > JCR session in it.
> >
>
> Ok, will add that today.
>
> > The JCR tests provide a good means to test if the basic ServiceProvider
> > stuff I wrote still roughly works.
> >
>
> Well, it would need to be ported to the new model as the interfaces have
>  changed.  Would you like to take a stab at that?  Doing so would help
> you get a better feeling for the new design.
>
> > My feeling is that CollectionInfo should not extend CollectionAdapter.
> > While I agree that people will probably implement both CollectionInfo
> > and CollectionAdapter by default, sometimes you want to just return the
> > metadata.
> >
>
> Agreed.  CollectionInfo can have a getCollectionAdapter method to
> connect the two.
>
> > Re: BasicAdapter - I'm still unconvinced about this API and its ability
> > to support the necessary semantics for generic APP stores.
> >
>
> Ditto.
>
> > CollectionAdapterManager should be in the basic package if we keep the
> > basic stuff around.
> >
>
> Take another look at CAM; I modified it so that it works generically
> with any CollectionAdapter, not just BasicAdapter.  This would allow any
> Provider implementation to use the properties file deployment mechanism
> independently of whether the BasicAdapter interface is used.
>
> > I get the feeling that
> > WorkspaceManager.checkMethod/checkTarget/getMethods can all probably go.
> > Could we not work that logic into the CollectionAdapter.extensionRequest
> ?
> >
>
> Not sure about this.
>
> > I still don't think its a good idea for a Provider to act as its own
> > WorkspaceManager per my previous email.
> >
>
> Noted, but it does make things easier in some cases (see the Simple
> example).  However, the design assumes they are separate things.
>
> > Shouldn't the WorkspaceInfo logic in DefaultProvider be in
> > WorkspaceManager?
> >
>
> Possibly; will take another look.
>
> - James
>
> > - Dan
> > James M Snell wrote:
> >> Ok, the server refactoring is coming along very well I think.  Thus
> >> far, I've been able to greatly simplify the overall design, as well as
> >> integrate the approaches implemented by Dan and the google feed-server
> >> team while still maintaining the flexibility of the original framework.
> >>
> >> The main components of the refactored design are:
> >>
> >>  * AbderaServlet
> >>  * ServiceContext
> >>  * Provider
> >>  * WorkspaceManager
> >>  * CollectionAdapter
> >>  * RequestContext
> >>  * ResponseContext
> >>  * Target
> >>  * Resolver<Target>
> >>  * Resolver<Subject>
> >>
> >> For the overwhelming majority of implementations, all an end developer
> >> will need to do is implement a CollectionAdapter, provide a
> >> TargetResolver, and glue the two together using a ServiceContext.
> >>
> >> The examples in the server_refactor test cases illustrates the three
> >> fundamental approaches.
> >>
> >> The application flow is simple:
> >>
> >>  * The AbderaServlet receives a request and creates a ServiceContext
> >>  * The ServiceContext creates a Provider instance
> >>  * The Provider instance uses it's associated WorkspaceManager to
> >>    select a CollectionAdapter.
> >>  * Once the CollectionAdapter is selected, the Provider forwards the
> >>    request on to the appropriate method
> >>
> >> In some cases, the Provider and the WorkspaceManager will be the same
> >> object.  In other cases, the Provider and the WorkspaceManager will be
> >> separate.
> >>
> >> Simple
> >> ------
> >>
> >> In the Simple example, the developer implements a CollectionAdapter, a
> >> Provider and a ServiceContext.
> >>
> >> The CollectionAdapter provides the guts of the implementation,
> >> providing implementations for each of the main prototocol operations
> >> such as getFeed, getEntry, etc.  These are the methods that used to
> >> exist on the old style provider interface.
> >>
> >> The Provider extends AbstractWorkspaceProvider which means the
> >> Provider is acting as it's own WorkspaceManager.
> >>
> >> The Provider/WorkspaceManager dispatches requests to the SimpleAdapter
> >> implementation.
> >>
> >> The SimpleServiceContext glues the Provider to the appropriate target
> >> resolver.
> >>
> >> Default
> >> -------
> >>
> >> In the Default example, the developer uses the same CollectionAdapter
> >> implementation used in the simple example but uses the DefaultProvider
> >> class.
> >>
> >> The Default example is similar in nature to the CollectionProvider
> >> stuff implemented by Dan in that it is the DefaultProvider's job to
> >> handle things like the creation of the Service document based on
> >> metadata provided by the developer.
> >>
> >> The simple and default examples are nearly identical with the
> >> exception that the default example supports multiple workspaces and
> >> collections.
> >>
> >> Basic
> >> -----
> >>
> >> The basic example (which is poorly named, I know) is essentially the
> >> google feed-server stuff, slightly modified so that it sits on top of
> >> the default provider implementation.
> >>
> >> The properties file based deployment is kept intact, but the Adapter
> >> interface is replaced by the BasicAdapter abstract class, which is an
> >> abstract CollectionAdapter implementation that defines the same
> >> abstract methods defined by the google feed-server Adapter interface.
> >> Existing google feed-server Adapter implementations can be ported to
> >> this design simply by replacing "implements Adapter" with "extends
> >> BasicAdapter".
> >>
> >> The implementation has been further modified to support the creation
> >> of a service document.  The code will read all of the *.properties
> >> files for the adapters and will generate a service document with one
> >> workspace and one collection per configured adapter.
> >>
> >> Service Documents
> >> -----------------
> >>
> >> In this design, the Provider is responsible for serving the service
> >> documents.  This means that the service document support will vary
> >> depending on the capabilities of the Provider implementation.
> >>
> >> CollectionAdapters
> >> ------------------
> >>
> >> In each of the three approaches, the same CollectionAdapter interface
> >> is used.  Also, with the possible exception of URI patterns used for
> >> links, CollectionAdapters should be independent of the Provider
> >> implementation used.  We need to find a more elegant way of tying
> >> Target Resolvers and Collection Adapters together while at the same
> >> time making it easier to manage links, but that can come later.  The
> >> more important thing is that once a CollectionAdapter is
> >> implementation, we should be able to use it regardless of which of the
> >> three models are selected.
> >>
> >> Media Collections
> >> -----------------
> >>
> >> The basic CollectionAdapter interface does not support media
> >> operations.  If you want to implement support for media collections,
> >> the CollectionAdapter has to implement the MediaCollectionAdapter
> >> interface.  The reason for this separation is to reduce the complexity
> >> of the simplest Atompub implementations that will only ever support
> >> Atom entries.
> >>
> >> Transactional
> >> -------------
> >>
> >> CollectionAdapter implementations can implement the Transactional
> >> interface if they wish to support transactional start/end/compensate
> >> semantics.  Provider implementations SHOULD call Transactional.start()
> >> before delegating to the CollectionAdapter method and
> >> Transactional.end() after delegating.  If an error occurs, the
> >> Provider SHOULD call Transactional.compensate().
> >>
> >> - James
> >
> >
>

Re: Feedback round 2 [was Re: Server Refactoring - Overview]

Posted by James M Snell <ja...@gmail.com>.
Dan Diephouse wrote:
> Looking good. But even more new comments! Hopefully you aren't sick of 
> me yet :-)
> 

Never!  Of course, large payments of small unmarked bills would help ;-)

> Can we collapse ServiceContext and Provider? I would propose then that 
> Provider gets getters/setters for Resolver<Subject>/<Target>. If we did 
> this we could get rid of ServiceContext too I think -- which would 
> remove one more step for the user. I did a similar thing with when I 
> made it implement Resolver<Target>. While I think this should be 
> pluggable, I really think users should not have to configure a resolver 
> by default.
> 

Quite possibly. Will take a look today.

> Along these lines I think we should remove the instantiation code which 
> is in DefaultServiceContext. IMO this is the job of a container of some 
> sort. I mean container in the broadest sense here.  For instance, I 
> think it could be wrapped up in something like a 
> PropertiesProviderBuilder. It could then configure a whole provider 
> instance - including resolvers, workspace manager, and collectionadapters.
> 

Agreed.

> Transactional.begin/end needs to take RequestContext so I can store a 
> JCR session in it.
> 

Ok, will add that today.

> The JCR tests provide a good means to test if the basic ServiceProvider 
> stuff I wrote still roughly works.
> 

Well, it would need to be ported to the new model as the interfaces have 
  changed.  Would you like to take a stab at that?  Doing so would help 
you get a better feeling for the new design.

> My feeling is that CollectionInfo should not extend CollectionAdapter. 
> While I agree that people will probably implement both CollectionInfo 
> and CollectionAdapter by default, sometimes you want to just return the 
> metadata.
> 

Agreed.  CollectionInfo can have a getCollectionAdapter method to 
connect the two.

> Re: BasicAdapter - I'm still unconvinced about this API and its ability 
> to support the necessary semantics for generic APP stores.
> 

Ditto.

> CollectionAdapterManager should be in the basic package if we keep the 
> basic stuff around.
> 

Take another look at CAM; I modified it so that it works generically 
with any CollectionAdapter, not just BasicAdapter.  This would allow any 
Provider implementation to use the properties file deployment mechanism 
independently of whether the BasicAdapter interface is used.

> I get the feeling that 
> WorkspaceManager.checkMethod/checkTarget/getMethods can all probably go. 
> Could we not work that logic into the CollectionAdapter.extensionRequest?
> 

Not sure about this.

> I still don't think its a good idea for a Provider to act as its own 
> WorkspaceManager per my previous email.
> 

Noted, but it does make things easier in some cases (see the Simple 
example).  However, the design assumes they are separate things.

> Shouldn't the WorkspaceInfo logic in DefaultProvider be in 
> WorkspaceManager?
> 

Possibly; will take another look.

- James

> - Dan
> James M Snell wrote:
>> Ok, the server refactoring is coming along very well I think.  Thus 
>> far, I've been able to greatly simplify the overall design, as well as 
>> integrate the approaches implemented by Dan and the google feed-server 
>> team while still maintaining the flexibility of the original framework.
>>
>> The main components of the refactored design are:
>>
>>  * AbderaServlet
>>  * ServiceContext
>>  * Provider
>>  * WorkspaceManager
>>  * CollectionAdapter
>>  * RequestContext
>>  * ResponseContext
>>  * Target
>>  * Resolver<Target>
>>  * Resolver<Subject>
>>
>> For the overwhelming majority of implementations, all an end developer 
>> will need to do is implement a CollectionAdapter, provide a 
>> TargetResolver, and glue the two together using a ServiceContext.
>>
>> The examples in the server_refactor test cases illustrates the three 
>> fundamental approaches.
>>
>> The application flow is simple:
>>
>>  * The AbderaServlet receives a request and creates a ServiceContext
>>  * The ServiceContext creates a Provider instance
>>  * The Provider instance uses it's associated WorkspaceManager to
>>    select a CollectionAdapter.
>>  * Once the CollectionAdapter is selected, the Provider forwards the
>>    request on to the appropriate method
>>
>> In some cases, the Provider and the WorkspaceManager will be the same 
>> object.  In other cases, the Provider and the WorkspaceManager will be 
>> separate.
>>
>> Simple
>> ------
>>
>> In the Simple example, the developer implements a CollectionAdapter, a 
>> Provider and a ServiceContext.
>>
>> The CollectionAdapter provides the guts of the implementation, 
>> providing implementations for each of the main prototocol operations 
>> such as getFeed, getEntry, etc.  These are the methods that used to 
>> exist on the old style provider interface.
>>
>> The Provider extends AbstractWorkspaceProvider which means the 
>> Provider is acting as it's own WorkspaceManager.
>>
>> The Provider/WorkspaceManager dispatches requests to the SimpleAdapter 
>> implementation.
>>
>> The SimpleServiceContext glues the Provider to the appropriate target 
>> resolver.
>>
>> Default
>> -------
>>
>> In the Default example, the developer uses the same CollectionAdapter 
>> implementation used in the simple example but uses the DefaultProvider 
>> class.
>>
>> The Default example is similar in nature to the CollectionProvider 
>> stuff implemented by Dan in that it is the DefaultProvider's job to 
>> handle things like the creation of the Service document based on 
>> metadata provided by the developer.
>>
>> The simple and default examples are nearly identical with the 
>> exception that the default example supports multiple workspaces and 
>> collections.
>>
>> Basic
>> -----
>>
>> The basic example (which is poorly named, I know) is essentially the 
>> google feed-server stuff, slightly modified so that it sits on top of 
>> the default provider implementation.
>>
>> The properties file based deployment is kept intact, but the Adapter 
>> interface is replaced by the BasicAdapter abstract class, which is an 
>> abstract CollectionAdapter implementation that defines the same 
>> abstract methods defined by the google feed-server Adapter interface.  
>> Existing google feed-server Adapter implementations can be ported to 
>> this design simply by replacing "implements Adapter" with "extends 
>> BasicAdapter".
>>
>> The implementation has been further modified to support the creation 
>> of a service document.  The code will read all of the *.properties 
>> files for the adapters and will generate a service document with one 
>> workspace and one collection per configured adapter.
>>
>> Service Documents
>> -----------------
>>
>> In this design, the Provider is responsible for serving the service 
>> documents.  This means that the service document support will vary 
>> depending on the capabilities of the Provider implementation.
>>
>> CollectionAdapters
>> ------------------
>>
>> In each of the three approaches, the same CollectionAdapter interface 
>> is used.  Also, with the possible exception of URI patterns used for 
>> links, CollectionAdapters should be independent of the Provider 
>> implementation used.  We need to find a more elegant way of tying 
>> Target Resolvers and Collection Adapters together while at the same 
>> time making it easier to manage links, but that can come later.  The 
>> more important thing is that once a CollectionAdapter is 
>> implementation, we should be able to use it regardless of which of the 
>> three models are selected.
>>
>> Media Collections
>> -----------------
>>
>> The basic CollectionAdapter interface does not support media 
>> operations.  If you want to implement support for media collections, 
>> the CollectionAdapter has to implement the MediaCollectionAdapter 
>> interface.  The reason for this separation is to reduce the complexity 
>> of the simplest Atompub implementations that will only ever support 
>> Atom entries.
>>
>> Transactional
>> -------------
>>
>> CollectionAdapter implementations can implement the Transactional 
>> interface if they wish to support transactional start/end/compensate 
>> semantics.  Provider implementations SHOULD call Transactional.start() 
>> before delegating to the CollectionAdapter method and 
>> Transactional.end() after delegating.  If an error occurs, the 
>> Provider SHOULD call Transactional.compensate().
>>
>> - James
> 
> 

Feedback round 2 [was Re: Server Refactoring - Overview]

Posted by Dan Diephouse <da...@mulesource.com>.
Looking good. But even more new comments! Hopefully you aren't sick of 
me yet :-)

Can we collapse ServiceContext and Provider? I would propose then that 
Provider gets getters/setters for Resolver<Subject>/<Target>. If we did 
this we could get rid of ServiceContext too I think -- which would 
remove one more step for the user. I did a similar thing with when I 
made it implement Resolver<Target>. While I think this should be 
pluggable, I really think users should not have to configure a resolver 
by default.

Along these lines I think we should remove the instantiation code which 
is in DefaultServiceContext. IMO this is the job of a container of some 
sort. I mean container in the broadest sense here.  For instance, I 
think it could be wrapped up in something like a 
PropertiesProviderBuilder. It could then configure a whole provider 
instance - including resolvers, workspace manager, and collectionadapters.

Transactional.begin/end needs to take RequestContext so I can store a 
JCR session in it.

The JCR tests provide a good means to test if the basic ServiceProvider 
stuff I wrote still roughly works.

My feeling is that CollectionInfo should not extend CollectionAdapter. 
While I agree that people will probably implement both CollectionInfo 
and CollectionAdapter by default, sometimes you want to just return the 
metadata.

Re: BasicAdapter - I'm still unconvinced about this API and its ability 
to support the necessary semantics for generic APP stores.

CollectionAdapterManager should be in the basic package if we keep the 
basic stuff around.

I get the feeling that 
WorkspaceManager.checkMethod/checkTarget/getMethods can all probably go. 
Could we not work that logic into the CollectionAdapter.extensionRequest?

I still don't think its a good idea for a Provider to act as its own 
WorkspaceManager per my previous email.

Shouldn't the WorkspaceInfo logic in DefaultProvider be in WorkspaceManager?

- Dan
James M Snell wrote:
> Ok, the server refactoring is coming along very well I think.  Thus 
> far, I've been able to greatly simplify the overall design, as well as 
> integrate the approaches implemented by Dan and the google feed-server 
> team while still maintaining the flexibility of the original framework.
>
> The main components of the refactored design are:
>
>  * AbderaServlet
>  * ServiceContext
>  * Provider
>  * WorkspaceManager
>  * CollectionAdapter
>  * RequestContext
>  * ResponseContext
>  * Target
>  * Resolver<Target>
>  * Resolver<Subject>
>
> For the overwhelming majority of implementations, all an end developer 
> will need to do is implement a CollectionAdapter, provide a 
> TargetResolver, and glue the two together using a ServiceContext.
>
> The examples in the server_refactor test cases illustrates the three 
> fundamental approaches.
>
> The application flow is simple:
>
>  * The AbderaServlet receives a request and creates a ServiceContext
>  * The ServiceContext creates a Provider instance
>  * The Provider instance uses it's associated WorkspaceManager to
>    select a CollectionAdapter.
>  * Once the CollectionAdapter is selected, the Provider forwards the
>    request on to the appropriate method
>
> In some cases, the Provider and the WorkspaceManager will be the same 
> object.  In other cases, the Provider and the WorkspaceManager will be 
> separate.
>
> Simple
> ------
>
> In the Simple example, the developer implements a CollectionAdapter, a 
> Provider and a ServiceContext.
>
> The CollectionAdapter provides the guts of the implementation, 
> providing implementations for each of the main prototocol operations 
> such as getFeed, getEntry, etc.  These are the methods that used to 
> exist on the old style provider interface.
>
> The Provider extends AbstractWorkspaceProvider which means the 
> Provider is acting as it's own WorkspaceManager.
>
> The Provider/WorkspaceManager dispatches requests to the SimpleAdapter 
> implementation.
>
> The SimpleServiceContext glues the Provider to the appropriate target 
> resolver.
>
> Default
> -------
>
> In the Default example, the developer uses the same CollectionAdapter 
> implementation used in the simple example but uses the DefaultProvider 
> class.
>
> The Default example is similar in nature to the CollectionProvider 
> stuff implemented by Dan in that it is the DefaultProvider's job to 
> handle things like the creation of the Service document based on 
> metadata provided by the developer.
>
> The simple and default examples are nearly identical with the 
> exception that the default example supports multiple workspaces and 
> collections.
>
> Basic
> -----
>
> The basic example (which is poorly named, I know) is essentially the 
> google feed-server stuff, slightly modified so that it sits on top of 
> the default provider implementation.
>
> The properties file based deployment is kept intact, but the Adapter 
> interface is replaced by the BasicAdapter abstract class, which is an 
> abstract CollectionAdapter implementation that defines the same 
> abstract methods defined by the google feed-server Adapter interface.  
> Existing google feed-server Adapter implementations can be ported to 
> this design simply by replacing "implements Adapter" with "extends 
> BasicAdapter".
>
> The implementation has been further modified to support the creation 
> of a service document.  The code will read all of the *.properties 
> files for the adapters and will generate a service document with one 
> workspace and one collection per configured adapter.
>
> Service Documents
> -----------------
>
> In this design, the Provider is responsible for serving the service 
> documents.  This means that the service document support will vary 
> depending on the capabilities of the Provider implementation.
>
> CollectionAdapters
> ------------------
>
> In each of the three approaches, the same CollectionAdapter interface 
> is used.  Also, with the possible exception of URI patterns used for 
> links, CollectionAdapters should be independent of the Provider 
> implementation used.  We need to find a more elegant way of tying 
> Target Resolvers and Collection Adapters together while at the same 
> time making it easier to manage links, but that can come later.  The 
> more important thing is that once a CollectionAdapter is 
> implementation, we should be able to use it regardless of which of the 
> three models are selected.
>
> Media Collections
> -----------------
>
> The basic CollectionAdapter interface does not support media 
> operations.  If you want to implement support for media collections, 
> the CollectionAdapter has to implement the MediaCollectionAdapter 
> interface.  The reason for this separation is to reduce the complexity 
> of the simplest Atompub implementations that will only ever support 
> Atom entries.
>
> Transactional
> -------------
>
> CollectionAdapter implementations can implement the Transactional 
> interface if they wish to support transactional start/end/compensate 
> semantics.  Provider implementations SHOULD call Transactional.start() 
> before delegating to the CollectionAdapter method and 
> Transactional.end() after delegating.  If an error occurs, the 
> Provider SHOULD call Transactional.compensate().
>
> - James


-- 
Dan Diephouse
MuleSource
http://mulesource.com | http://netzooid.com/blog