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/19 02:08:10 UTC
Server module refactoring
Ok, given the discussions around Adapter/CollectionProvider and the
complex way the existing server code has evolved, I decided to take a
step back and look at the server module as a whole. I believe I've come
up with a refactoring that will greatly simplify things overall and make
it easier to support not only the capabilities that our friends from
google want, but also things like extension methods (e.g. patch),
protocol extensions (e.g. opensearch), etc.
Note: the refactoring would actually take place above the functionality
that the google feed-server provides, so there could potentially be very
little impact on that work, but we'll address that shortly.
The refactoring that I have in mind changes everything from
AbderaServlet up through CollectionProvider and is focused on reducing
the number of moving parts and number of things a developer has to do
when implementing an atompub server.
In this note, I want to provide a quick run through of the changes I
have in mind. I'll post some of the preliminary implementation ideas to
a jira issue.
Structure:
Package: org.apache.abdera.protocol.server.refactor
CollectionAdapter.java
MediaCollectionAdapter.java
Provider.java
ProviderHelper.java
Transactional.java
WorkspaceManager.java
Package: org.apache.abdera.protocol.server.refactor.impl
AbstractProvider.java
AbstractWorkspaceManager.java
AbstractWorkspaceManagerProvider.java
The code flow in the current implementation is:
AbderaServlet -> RequestHandler -> Provider -> CollectionProvider
After refactoring, RequestHandler will be removed completely. The
Provider interface is simplified to a single request method.
There will be a single base abstract Provider implementation provided
but advanced developers will be able to replace that implementation with
their own.
The default provider implementation will extend
AbstractWorkspaceManagerProvider.java. This class implements boththe
Provider and WorkspaceManager interfaces.
The WorkspaceManager is equivalent to the current WorkspaceInfo
interface. It's primary function is to lookup the appropriate
CollectionAdapter instance.
CollectionAdapter is the equivalent to the current CollectionProvider
interface.
MediaCollectionAdapter extends CollectionAdapter to provide methods for
handling media resources.
A CollectionAdapter instance can choose to implement the Provider
interface in order to support extension methods.
A CollectionAdapter instance can choose to implement the Transactional
interface if it wishes to support begin/end/compensate semantics.
All of the methods on CollectionAdapter take RequestContext and return
ResponseContext, maintaining the ability to parameterize requests and
utilize streaming responses.
The flow is simple: request comes into the servlet, which dispatches to
the Provider. The Provider gets the WorkspaceManager and uses it to get
the CollectionAdapter. If the request is for a known method and a known
target type, the provider dispatches to the appropriate method on
CollectionAdapter (e.g. getFeed, deleteEntry, etc). If the request is
for an unknown method and an unknown target type, the provider checks to
see if the CollectionAdapter implements the Provider interface, and if
so, forwards the request on to it for processing, otherwise, an
unsupported method response is returned. If CollectionAdapter
implements Transactional, all of this is preceeded by a
Transactional.begin() and proceeded by Transactional.end().
A CollectionAdapter can be implemented that wraps the simplified Adapter
interface used by feed-server. Initially, this interface would not
implement either Transactional or MediaCollectionAdapter keeping it in
line with the current functionality offered by feed-server.
Additional refactorings would be required to implement this but overall
the code structure would be greatly simplified, more logical, easier to
extend, easier to maintain, and more accessible for end users.
Anyway, please take a look and let me know what you think.
- James
Re: Server module refactoring
Posted by James M Snell <ja...@gmail.com>.
Dan Diephouse wrote:
> I just took a look at the refactoring. Overall I like it.
>
Good to hear.
> Some comments:
>
> Most of my comments have to do with the ext package. I like the
> interfaces for the most part in the top level package. But I think to
> some degree the separation which has occurred inside the ext/basic
> packages is unecessary.
>
Agreed.
> AbstractProvider already includes the concepts of CollectionAdapter &
> WorkspaceManager. So why have so many derivative implementations? There
> is AbstractProivder, AbstractWorkspaceManagerProvider, BasicProvider,
> ExtendedProvider. They are all slight variations on the same thing and
> should all be combined into one thing IMO. I was kind of on the fence
> before, but after seeing the class proliferation, think its a bad idea
> to have a provider implement CollectionAdapter & WorkspaceManager. It
> creates an overly complex code base and will be confusing for users -
> i.e. which Provider do I use? Lets make the typical answer to that
> question just one answer unless they have to override some advanced
> functionality. Then the process of writing a server becomes conceptually
> simpler:
> - Write a CollectionAdapter
> - If necessary write a workspace manager
> - Glue it together with a ServiceContext and a provider
> See how this eliminates a step and confusion from the process?
>
> Along these lines:
> - ExtendedWorkspaceManager -> WorkspaceManagerImpl, SimpleWorkspaceInfo
> -> WorkspaceImpl (I personally like Impl better, but whatever)
> - Collapse NamedCollectionAdapter into CollectionAdapter
> - Delete AbstractWorkspaceManagerProvider,
> AbstractNamedCollectionAdapter, redundant Basic* stuff, etc
>
> And see how many classes can be removed? :-)
>
Again agreed. I would have combined much of this stuff already but I
wanted to keep the various approaches separate in this first revision
and then start iterating to simplify things. Mainly, I'm still not
convinced that there is a need for the BasicAdapter interface. I
understand what the feed-server stuff is doing but I think the
additional interfaces causes more difficulty than it is worth.
> Other comments:
> - Can we please move to TestNG or JUnit4? The test code to deal with
> servers is fairly hackish and this would alleviate that.
> - I find the code style a little unreadable. I'm hesitant to bring it up
> though as its a neverending battle. If I had two wishes though they
> would be that we don't break constrcutor/method lines unless necessary
> and we move to 4 spaces :-)
>
> I have more thoughts, but I need to hop on a plane. Nice work James and
> looking forward to digging in more soon.
> - Dan
>
> --
> Dan Diephouse
> MuleSource
> http://mulesource.com | http://netzooid.com/blog
>
>
Re: Server module refactoring
Posted by Dan Diephouse <da...@mulesource.com>.
I'll take a look later tonight or early in the morning and let you know
my thoughts. No need to rush to write something up for me as the code is
probably OK for now.
- Dan
James M Snell wrote:
> Ok, many changes. Later this evening (after the kids are in bed) I
> will write up a note summarizing the changes and will take a first
> stab at a brief server implementation guide based on the revised code.
>
> Please take a look and let me know your thoughts.
>
> - James
>
> Dan Diephouse wrote:
>> I just took a look at the refactoring. Overall I like it.
>>
>> Some comments:
>>
>> Most of my comments have to do with the ext package. I like the
>> interfaces for the most part in the top level package. But I think to
>> some degree the separation which has occurred inside the ext/basic
>> packages is unecessary.
>>
>> AbstractProvider already includes the concepts of CollectionAdapter &
>> WorkspaceManager. So why have so many derivative implementations?
>> There is AbstractProivder, AbstractWorkspaceManagerProvider,
>> BasicProvider, ExtendedProvider. They are all slight variations on
>> the same thing and should all be combined into one thing IMO. I was
>> kind of on the fence before, but after seeing the class
>> proliferation, think its a bad idea to have a provider implement
>> CollectionAdapter & WorkspaceManager. It creates an overly complex
>> code base and will be confusing for users - i.e. which Provider do I
>> use? Lets make the typical answer to that question just one answer
>> unless they have to override some advanced functionality. Then the
>> process of writing a server becomes conceptually simpler:
>> - Write a CollectionAdapter
>> - If necessary write a workspace manager
>> - Glue it together with a ServiceContext and a provider
>> See how this eliminates a step and confusion from the process?
>>
>> Along these lines:
>> - ExtendedWorkspaceManager -> WorkspaceManagerImpl,
>> SimpleWorkspaceInfo -> WorkspaceImpl (I personally like Impl better,
>> but whatever)
>> - Collapse NamedCollectionAdapter into CollectionAdapter
>> - Delete AbstractWorkspaceManagerProvider,
>> AbstractNamedCollectionAdapter, redundant Basic* stuff, etc
>>
>> And see how many classes can be removed? :-)
>>
>> Other comments:
>> - Can we please move to TestNG or JUnit4? The test code to deal with
>> servers is fairly hackish and this would alleviate that.
>> - I find the code style a little unreadable. I'm hesitant to bring it
>> up though as its a neverending battle. If I had two wishes though
>> they would be that we don't break constrcutor/method lines unless
>> necessary and we move to 4 spaces :-)
>>
>> I have more thoughts, but I need to hop on a plane. Nice work James
>> and looking forward to digging in more soon.
>> - Dan
>>
>> --
>> Dan Diephouse
>> MuleSource
>> http://mulesource.com | http://netzooid.com/blog
>>
>>
--
Dan Diephouse
MuleSource
http://mulesource.com | http://netzooid.com/blog
Re: Server module refactoring
Posted by James M Snell <ja...@gmail.com>.
Ok, many changes. Later this evening (after the kids are in bed) I will
write up a note summarizing the changes and will take a first stab at a
brief server implementation guide based on the revised code.
Please take a look and let me know your thoughts.
- James
Dan Diephouse wrote:
> I just took a look at the refactoring. Overall I like it.
>
> Some comments:
>
> Most of my comments have to do with the ext package. I like the
> interfaces for the most part in the top level package. But I think to
> some degree the separation which has occurred inside the ext/basic
> packages is unecessary.
>
> AbstractProvider already includes the concepts of CollectionAdapter &
> WorkspaceManager. So why have so many derivative implementations? There
> is AbstractProivder, AbstractWorkspaceManagerProvider, BasicProvider,
> ExtendedProvider. They are all slight variations on the same thing and
> should all be combined into one thing IMO. I was kind of on the fence
> before, but after seeing the class proliferation, think its a bad idea
> to have a provider implement CollectionAdapter & WorkspaceManager. It
> creates an overly complex code base and will be confusing for users -
> i.e. which Provider do I use? Lets make the typical answer to that
> question just one answer unless they have to override some advanced
> functionality. Then the process of writing a server becomes conceptually
> simpler:
> - Write a CollectionAdapter
> - If necessary write a workspace manager
> - Glue it together with a ServiceContext and a provider
> See how this eliminates a step and confusion from the process?
>
> Along these lines:
> - ExtendedWorkspaceManager -> WorkspaceManagerImpl, SimpleWorkspaceInfo
> -> WorkspaceImpl (I personally like Impl better, but whatever)
> - Collapse NamedCollectionAdapter into CollectionAdapter
> - Delete AbstractWorkspaceManagerProvider,
> AbstractNamedCollectionAdapter, redundant Basic* stuff, etc
>
> And see how many classes can be removed? :-)
>
> Other comments:
> - Can we please move to TestNG or JUnit4? The test code to deal with
> servers is fairly hackish and this would alleviate that.
> - I find the code style a little unreadable. I'm hesitant to bring it up
> though as its a neverending battle. If I had two wishes though they
> would be that we don't break constrcutor/method lines unless necessary
> and we move to 4 spaces :-)
>
> I have more thoughts, but I need to hop on a plane. Nice work James and
> looking forward to digging in more soon.
> - Dan
>
> --
> Dan Diephouse
> MuleSource
> http://mulesource.com | http://netzooid.com/blog
>
>
Re: Server module refactoring
Posted by Dan Diephouse <da...@mulesource.com>.
I just took a look at the refactoring. Overall I like it.
Some comments:
Most of my comments have to do with the ext package. I like the
interfaces for the most part in the top level package. But I think to
some degree the separation which has occurred inside the ext/basic
packages is unecessary.
AbstractProvider already includes the concepts of CollectionAdapter &
WorkspaceManager. So why have so many derivative implementations? There
is AbstractProivder, AbstractWorkspaceManagerProvider, BasicProvider,
ExtendedProvider. They are all slight variations on the same thing and
should all be combined into one thing IMO. I was kind of on the fence
before, but after seeing the class proliferation, think its a bad idea
to have a provider implement CollectionAdapter & WorkspaceManager. It
creates an overly complex code base and will be confusing for users -
i.e. which Provider do I use? Lets make the typical answer to that
question just one answer unless they have to override some advanced
functionality. Then the process of writing a server becomes conceptually
simpler:
- Write a CollectionAdapter
- If necessary write a workspace manager
- Glue it together with a ServiceContext and a provider
See how this eliminates a step and confusion from the process?
Along these lines:
- ExtendedWorkspaceManager -> WorkspaceManagerImpl, SimpleWorkspaceInfo
-> WorkspaceImpl (I personally like Impl better, but whatever)
- Collapse NamedCollectionAdapter into CollectionAdapter
- Delete AbstractWorkspaceManagerProvider,
AbstractNamedCollectionAdapter, redundant Basic* stuff, etc
And see how many classes can be removed? :-)
Other comments:
- Can we please move to TestNG or JUnit4? The test code to deal with
servers is fairly hackish and this would alleviate that.
- I find the code style a little unreadable. I'm hesitant to bring it up
though as its a neverending battle. If I had two wishes though they
would be that we don't break constrcutor/method lines unless necessary
and we move to 4 spaces :-)
I have more thoughts, but I need to hop on a plane. Nice work James and
looking forward to digging in more soon.
- Dan
--
Dan Diephouse
MuleSource
http://mulesource.com | http://netzooid.com/blog
Re: Server module refactoring
Posted by James M Snell <ja...@gmail.com>.
Dan Diephouse wrote:
> I've commented on a couple things which I have other thoughts on, but
> overall it looks good.
>
> James M Snell wrote:
>>
>> The default provider implementation will extend
>> AbstractWorkspaceManagerProvider.java. This class implements boththe
>> Provider and WorkspaceManager interfaces.
> I would also like to float the idea that the Provider should take a
> WorkspaceManager as a property/constructor. This way I as a user just
> implement WorkspaceManager which can look up collections from my
> database and pass it in as an argument to some stock Provider.
>>
>> The WorkspaceManager is equivalent to the current WorkspaceInfo
>> interface. It's primary function is to lookup the appropriate
>> CollectionAdapter instance.
> We still need a way to describe the workspaces though. A la
> WorkspaceInfo.getName/getCollectionProviders. Are you sure we don't need
> WorkspaceInfo still?
>
WorkspaceInfo is still going to be there, it will be used for
Provider/Adapter implentations that derived from what is currently your
CollectionProvider code, which I am currently in the process of
porting/adapting over the revised model. Once I finish porting and you
get a chance to review, I think it will make sense.
>>
>> A CollectionAdapter instance can choose to implement the Provider
>> interface in order to support extension methods.
> I'm not sure that provider is the right interface to do this as it mixes
> semantics a little bit. My alternative proposals would be to either:
> 1. have a fallback method built into CA like doOther(RequestContext) or
> something like that.
> 2. Make the Provider responsible for choosing a method via some sort of
> extensible dispatching mechanism
Yes, I'm not convinced Provider is right either. For now, it suited the
immediate need but I was planning to revisit it.
>>
>> A CollectionAdapter instance can choose to implement the Transactional
>> interface if it wishes to support begin/end/compensate semantics.
> I think this might be going a little bit overboard here in terms of
> interfaces. I would rather lean toward building this into the
> AbstractCollectionAdapter itself. A la the code snippet I published
> earlier which called begin/end inside.
>
> BTW, I also think we'll need to have begin/end points which we can
> intercept in the actual Provider implementation itself.
>
Noted. Once I finish the initial port, I'll check the code into a branch
so we can collectively review it and make whatever additional tweaks we
need.
> Overall, I like the simplified flow and increased coherency!
>
Excellent.
- James
> - Dan
>
Re: Server module refactoring
Posted by Dan Diephouse <da...@mulesource.com>.
I've commented on a couple things which I have other thoughts on, but
overall it looks good.
James M Snell wrote:
>
> The default provider implementation will extend
> AbstractWorkspaceManagerProvider.java. This class implements boththe
> Provider and WorkspaceManager interfaces.
I would also like to float the idea that the Provider should take a
WorkspaceManager as a property/constructor. This way I as a user just
implement WorkspaceManager which can look up collections from my
database and pass it in as an argument to some stock Provider.
>
> The WorkspaceManager is equivalent to the current WorkspaceInfo
> interface. It's primary function is to lookup the appropriate
> CollectionAdapter instance.
We still need a way to describe the workspaces though. A la
WorkspaceInfo.getName/getCollectionProviders. Are you sure we don't need
WorkspaceInfo still?
>
> A CollectionAdapter instance can choose to implement the Provider
> interface in order to support extension methods.
I'm not sure that provider is the right interface to do this as it mixes
semantics a little bit. My alternative proposals would be to either:
1. have a fallback method built into CA like doOther(RequestContext) or
something like that.
2. Make the Provider responsible for choosing a method via some sort of
extensible dispatching mechanism
>
> A CollectionAdapter instance can choose to implement the Transactional
> interface if it wishes to support begin/end/compensate semantics.
I think this might be going a little bit overboard here in terms of
interfaces. I would rather lean toward building this into the
AbstractCollectionAdapter itself. A la the code snippet I published
earlier which called begin/end inside.
BTW, I also think we'll need to have begin/end points which we can
intercept in the actual Provider implementation itself.
Overall, I like the simplified flow and increased coherency!
- Dan
--
Dan Diephouse
MuleSource
http://mulesource.com | http://netzooid.com/blog