You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by Joachim Draeger <jd...@gmx.de> on 2006/10/28 18:51:13 UTC

BasicMailboxSession (aka MessageRepository)

Hi all!

I guess it is wished that the API for just accessing user inboxes should
stay as easy as possible. 
That's why I'm proposing a separate Interface that only contains core
functionalities.

Just like addUser has been moved from James class to UsersRepository,
getUserInbox could be moved to MailboxManagerProvider (alias
MailboxService):

package org.apache.james.mailboxservice;

interface MailboxService {
  BasicMailboxSession getBasicInboxSession(User user);

  /** @param user the authorized User for checking credentials 
      @param mailboxName a logical/hierarchical mailbox name **/ 

  BasicMailboxSession getBasicMailboxSession(
       User user, String mailboxName);

}

interface BasicMailbox {

    /** @return the key */
    String store(MimeMessage message) throws MessagingException;

    /** @return keys */
    Collection list() throws MessagingException;

    MimeMessage retrieve(String key);

    /**
     * key changes by updating
     * @param key the current key
     * @return the new key
     */
    String update(String key, MimeMessage message)
            throws MessagingException;

    void remove(String key)
            throws MessagingException;
}

interface BasicMailboxSession extends BasicMailbox, MailboxSession {}

public interface MailboxSession {
    public void close();
    public boolean isWriteable();
}

The main differences to current MailRepository are:

* keys are generated by mailbox
* separate store/update
* sessions have to be explicitly closed. (and not weak referenced and
_maybe_ gc'ed away)
* logical mailbox names that are mapped to physical backends

Okay there is one point that is a bit more difficult: 
ToRepository Mailet, which accepts a url. 
It is used for mail that is not delivered to a user like spam or mail
that can't be delivered.
I guess the ability to put this repositories where ever one wants is
quite popular.
Maybe we could use a logical #system name space here like #system.spam
or #system.address-error.
For example this could be mapped like: #system.* -> file:/var/mail/*

BasicMailboxSession mailboxSession= mailboxService.
       getBasicMailboxSession(User.SMTP, "#system.spam");
mailboxSession.store(aSpamMimeMessage);
mailboxSession.close();      

Roadmap:

1. discussion
2. vote
3. deprecate MailRepository and James.getUserInbox() (not to break
backward compatibility)
4. provide BasicMailbox wrappers around MailRepository 
5. refactor current components to use MailboxService.

What do you think?

Joachim



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


Re: BasicMailboxSession (aka MessageRepository)

Posted by Stefano Bagnara <ap...@bago.org>.
I just noticed I never replied to this.
+1 to everything.

The plan fits perfectly in our step-by-step "revolution by evolution".

I see you already created a new branch to work on this! Cool!

Stefano

Joachim Draeger wrote:
> Stefano Bagnara schrieb:
>>
>> db / dbfile / file are already logical mount points.
>> I don't like it too much because we use this logical mountpoints for 
>> different contents (mailrepository/spoolrepository/generic db access).
>>
>> I think we should simply rewrite our repository store to provide a 
>> single url type for every type of object available, like a virtual 
>> file system.
>>
>> What I expect is something like spool://some/path, message://some/path.
>> Then in the store we really define what specific implementation we 
>> want to mount in every single mount point.
>>
>> I think this would be something in the middle between what we 
>> currently have and what you try to achieve with the "#some.path" 
>> logical name.
> We are probably thinking of something very similar. :-)
>> I also like more the use of the "#some.path" instead of 
>> "message://some/path" because I think this make less confusion not 
>> using something similar to real file system paths.
> the #mail.joe.INBOX or #users.joe.INBOX is a commonly used 
> quasi-standard for IMAP. It's called namespaces there. Theoretical 
> naming schemes could be freely defined when using IMAP, but I'm not sure 
> whether a URL like message://some/path  will work. (A slash as a 
> hierarchy delimiter is okay)
> Anyway IMO we should follow a commonly used IMAP standard here. People 
> with IMAP experience (probably many mail-server administrators) will 
> feel at once familiar.
> We should avoid translating a custom James virtual naming scheme for 
> IMAP access..
>> <messagestore class="VirtualStore">
>>   <repository mountpoint="#some" class="TorqueMessageRepository">
>>     <tablename>foo</tablename>
>>   </repository>
>>   <repository mountpoint="#other" class="FileMessageRepository">
>>     <filepath>%{app.root}/var/mount</filepath>
>>   </repository>
>>   <!-- this is even more advanced because "nested" would be a file 
>> repository with the torque repository parent -->
>>   <repository mountpoint="#some.nested" class="FileMessageRepository">
>>     <filepath>%{app.root}/var/nested</filepath>
>>   </repository>
>> </messagestore>
>>
>> or alternatively something like:
>>
>> <messagestore class="VirtualStore">
>>   <repository mountpoint="#some" class="VirtualStore>
>>     <!-- default repository for this virtual store -->
>>     <repository class="TorqueMessageRepository">
>>       <tablename>foo</tablename>
>>     </repository>
>>     <repository mountpoint="nested" class="FileMessageRepository">
>>       <filepath>%{app.root}/var/nested</filepath>
>>     </repository>
>>   </repository>
>>   <repository mountpoint="#other" class="FileMessageRepository">
>>     <filepath>%{app.root}/var/mount</filepath>
>>   </repository>
>> </messagestore>
> I would prefer the first example. For MailboxManager I've decided to use 
> a "flat hierarchy". Until it is really needed mailbox names (that 
> consist of a logical path) are just mailbox names and treated hierarchy 
> agnostic.
> Most of the times no hierarchy is needed and would be just overhead.
>> Every message repository simply have to implement a method where the 
>> repository itself is created with a parameter that indicate the 
>> relative path between the mountpoint and the real path requested: as 
>> an example if I ask #some.nested.foo.bar the VirtualStore 
>> implementation will be called with #some.nested.foo.bar. From an 
>> internal lookup it will find #some.nested is the most specific mount 
>> point and will delegate to FileMessageRepository that will be called 
>> with ".foo.bar" as a detail on the specific repository requested.
>>
>> Does this make sense?
> This is exactly what I have in mind.
> 
>> Now that I wrote all of this, I understand that probably this is what 
>> you are proposing, with the difference that you probably would have 
>> used something like this:
>>
>> <messagestore class="VirtualStore">
>>   <repository mountpoint="#some" repositoryUrl="db://maildb/foo" />
>>   <repository mountpoint="#other" repositoryUrl="file://var/mount" />
>>   <repository mountpoint="#some.nested" 
>> repositoryUrl="file://var/nested" />
>> </messagestore>
>>
>> This way you would still use the current mailstore to retrieve each 
>> repository. It is simply one more layer (that I tried to merge to the 
>> current one)
> This would be my first approach because I'm going to try to be backward 
> compatible.This way we wouldn't need to change current mailstore.
> 
>> Did I understand your proposal? Is my "simplified proposal" acceptable?
> Yes I think we agree. Your merged configuration proposal will be perfect 
> in a longer term.
> Maybe we could even avoid the intermediate step #some -> url:// but I 
> haven't done any further investigations in that direction.
>> If all of this is ok, how would you manage the retrieval of a "child" 
>> repository? Adding ".child" to the logical name and retrieving it from 
>> the store? Or alternatively adding a getChild("child") method to the 
>> repository (mailboxsession) interface?
> For the current implementation I decided to use the "string 
> concatenation" way. The mailboxes will be completely hierarchy agnostic. 
> I'm quite happy with that decision so far.
> This way the mailbox does not need a connection to the store and there 
> is a central point where the mapping is done.
> 
> There are even more good reasons:
> * IMAP does not require to fetch child or parent mailboxes
> * There is no efficient possibility to store hierarchies into a RDBMS
> 
> Joachim



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


Re: BasicMailboxSession (aka MessageRepository)

Posted by Joachim Draeger <jd...@joachim-draeger.de>.
Stefano Bagnara schrieb:
>
> db / dbfile / file are already logical mount points.
> I don't like it too much because we use this logical mountpoints for 
> different contents (mailrepository/spoolrepository/generic db access).
>
> I think we should simply rewrite our repository store to provide a 
> single url type for every type of object available, like a virtual 
> file system.
>
> What I expect is something like spool://some/path, message://some/path.
> Then in the store we really define what specific implementation we 
> want to mount in every single mount point.
>
> I think this would be something in the middle between what we 
> currently have and what you try to achieve with the "#some.path" 
> logical name.
We are probably thinking of something very similar. :-)
> I also like more the use of the "#some.path" instead of 
> "message://some/path" because I think this make less confusion not 
> using something similar to real file system paths.
the #mail.joe.INBOX or #users.joe.INBOX is a commonly used 
quasi-standard for IMAP. It's called namespaces there. Theoretical 
naming schemes could be freely defined when using IMAP, but I'm not sure 
whether a URL like message://some/path  will work. (A slash as a 
hierarchy delimiter is okay)
Anyway IMO we should follow a commonly used IMAP standard here. People 
with IMAP experience (probably many mail-server administrators) will 
feel at once familiar.
We should avoid translating a custom James virtual naming scheme for 
IMAP access..
> <messagestore class="VirtualStore">
>   <repository mountpoint="#some" class="TorqueMessageRepository">
>     <tablename>foo</tablename>
>   </repository>
>   <repository mountpoint="#other" class="FileMessageRepository">
>     <filepath>%{app.root}/var/mount</filepath>
>   </repository>
>   <!-- this is even more advanced because "nested" would be a file 
> repository with the torque repository parent -->
>   <repository mountpoint="#some.nested" class="FileMessageRepository">
>     <filepath>%{app.root}/var/nested</filepath>
>   </repository>
> </messagestore>
>
> or alternatively something like:
>
> <messagestore class="VirtualStore">
>   <repository mountpoint="#some" class="VirtualStore>
>     <!-- default repository for this virtual store -->
>     <repository class="TorqueMessageRepository">
>       <tablename>foo</tablename>
>     </repository>
>     <repository mountpoint="nested" class="FileMessageRepository">
>       <filepath>%{app.root}/var/nested</filepath>
>     </repository>
>   </repository>
>   <repository mountpoint="#other" class="FileMessageRepository">
>     <filepath>%{app.root}/var/mount</filepath>
>   </repository>
> </messagestore>
I would prefer the first example. For MailboxManager I've decided to use 
a "flat hierarchy". Until it is really needed mailbox names (that 
consist of a logical path) are just mailbox names and treated hierarchy 
agnostic.
Most of the times no hierarchy is needed and would be just overhead.
> Every message repository simply have to implement a method where the 
> repository itself is created with a parameter that indicate the 
> relative path between the mountpoint and the real path requested: as 
> an example if I ask #some.nested.foo.bar the VirtualStore 
> implementation will be called with #some.nested.foo.bar. From an 
> internal lookup it will find #some.nested is the most specific mount 
> point and will delegate to FileMessageRepository that will be called 
> with ".foo.bar" as a detail on the specific repository requested.
>
> Does this make sense?
This is exactly what I have in mind.

> Now that I wrote all of this, I understand that probably this is what 
> you are proposing, with the difference that you probably would have 
> used something like this:
>
> <messagestore class="VirtualStore">
>   <repository mountpoint="#some" repositoryUrl="db://maildb/foo" />
>   <repository mountpoint="#other" repositoryUrl="file://var/mount" />
>   <repository mountpoint="#some.nested" 
> repositoryUrl="file://var/nested" />
> </messagestore>
>
> This way you would still use the current mailstore to retrieve each 
> repository. It is simply one more layer (that I tried to merge to the 
> current one)
This would be my first approach because I'm going to try to be backward 
compatible.This way we wouldn't need to change current mailstore.

> Did I understand your proposal? Is my "simplified proposal" acceptable?
Yes I think we agree. Your merged configuration proposal will be perfect 
in a longer term.
Maybe we could even avoid the intermediate step #some -> url:// but I 
haven't done any further investigations in that direction.
> If all of this is ok, how would you manage the retrieval of a "child" 
> repository? Adding ".child" to the logical name and retrieving it from 
> the store? Or alternatively adding a getChild("child") method to the 
> repository (mailboxsession) interface?
For the current implementation I decided to use the "string 
concatenation" way. The mailboxes will be completely hierarchy agnostic. 
I'm quite happy with that decision so far.
This way the mailbox does not need a connection to the store and there 
is a central point where the mapping is done.

There are even more good reasons:
 * IMAP does not require to fetch child or parent mailboxes
 * There is no efficient possibility to store hierarchies into a RDBMS

Joachim


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


Re: BasicMailboxSession (aka MessageRepository)

Posted by Stefano Bagnara <ap...@bago.org>.
Joachim Draeger wrote:
> Am Samstag, den 28.10.2006, 18:07 +0100 schrieb Danny Angus: 
>> On 10/28/06, Joachim Draeger <jd...@gmx.de> wrote:
>>> Maybe we could use a logical #system name space here like #system.spam
>>> or #system.address-error.
>>> For example this could be mapped like: #system.* -> file:/var/mail/*
>> Yuk, whats wrong with file:/var/mail if thats really where you want to put it??
> 
> Why does linux mount different filesystems into one logical root
> filesystem?
> 
> (The idea was #system.spam becomes translated to file:/var/mail/spam)
> 
> Benefits of logical names:
> 
> * dealing with hierarchy, Quota and ACLs
> * they could be accessed in a programmatic way by IMAP :-)
> * redundancy - if you have many ToRepository that all resist under
>    file:/var/mail and you switch to db you have to modify all the Urls
> * safety - custom code can modify only the logical name 

db / dbfile / file are already logical mount points.
I don't like it too much because we use this logical mountpoints for 
different contents (mailrepository/spoolrepository/generic db access).

I think we should simply rewrite our repository store to provide a 
single url type for every type of object available, like a virtual file 
system.

What I expect is something like spool://some/path, message://some/path.
Then in the store we really define what specific implementation we want 
to mount in every single mount point.

I think this would be something in the middle between what we currently 
have and what you try to achieve with the "#some.path" logical name.

I also like more the use of the "#some.path" instead of 
"message://some/path" because I think this make less confusion not using 
something similar to real file system paths.

This idea already appeared here:
http://wiki.apache.org/james/JamesV3/Plans ("Message repository 
directory structure")

And maybe I already talked about this in past.

<messagestore class="VirtualStore">
   <repository mountpoint="#some" class="TorqueMessageRepository">
     <tablename>foo</tablename>
   </repository>
   <repository mountpoint="#other" class="FileMessageRepository">
     <filepath>%{app.root}/var/mount</filepath>
   </repository>
   <!-- this is even more advanced because "nested" would be a file 
repository with the torque repository parent -->
   <repository mountpoint="#some.nested" class="FileMessageRepository">
     <filepath>%{app.root}/var/nested</filepath>
   </repository>
</messagestore>

or alternatively something like:

<messagestore class="VirtualStore">
   <repository mountpoint="#some" class="VirtualStore>
     <!-- default repository for this virtual store -->
     <repository class="TorqueMessageRepository">
       <tablename>foo</tablename>
     </repository>
     <repository mountpoint="nested" class="FileMessageRepository">
       <filepath>%{app.root}/var/nested</filepath>
     </repository>
   </repository>
   <repository mountpoint="#other" class="FileMessageRepository">
     <filepath>%{app.root}/var/mount</filepath>
   </repository>
</messagestore>

Every message repository simply have to implement a method where the 
repository itself is created with a parameter that indicate the relative 
path between the mountpoint and the real path requested: as an example 
if I ask #some.nested.foo.bar the VirtualStore implementation will be 
called with #some.nested.foo.bar. From an internal lookup it will find 
#some.nested is the most specific mount point and will delegate to 
FileMessageRepository that will be called with ".foo.bar" as a detail on 
the specific repository requested.

Does this make sense?
Imho this is much more easy than what we have now, and even more 
powerful. Today if you want to move from file to db repositories you 
have to change a lot of configurations. After this new feature the 
change would need a single edit in the config file.

Now that I wrote all of this, I understand that probably this is what 
you are proposing, with the difference that you probably would have used 
something like this:

<messagestore class="VirtualStore">
   <repository mountpoint="#some" repositoryUrl="db://maildb/foo" />
   <repository mountpoint="#other" repositoryUrl="file://var/mount" />
   <repository mountpoint="#some.nested" 
repositoryUrl="file://var/nested" />
</messagestore>

This way you would still use the current mailstore to retrieve each 
repository. It is simply one more layer (that I tried to merge to the 
current one)

Did I understand your proposal? Is my "simplified proposal" acceptable?

If all of this is ok, how would you manage the retrieval of a "child" 
repository? Adding ".child" to the logical name and retrieving it from 
the store? Or alternatively adding a getChild("child") method to the 
repository (mailboxsession) interface?

Stefano


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


Re: BasicMailboxSession (aka MessageRepository)

Posted by Norman Maurer <nm...@byteaction.de>.
Stefano Bagnara schrieb:
> Joachim Draeger wrote:
>> Am Samstag, den 28.10.2006, 18:07 +0100 schrieb Danny Angus:
>>> On 10/28/06, Joachim Draeger <jd...@gmx.de> wrote:
>>>> Maybe we could use a logical #system name space here like #system.spam
>>>> or #system.address-error.
>>>> For example this could be mapped like: #system.* -> file:/var/mail/*
>>> Yuk, whats wrong with file:/var/mail if thats really where you want
>>> to put it??
>>
>> Why does linux mount different filesystems into one logical root
>> filesystem?
>>
>> (The idea was #system.spam becomes translated to file:/var/mail/spam)
>>
>> Benefits of logical names:
>>
>> * dealing with hierarchy, Quota and ACLs
>> * they could be accessed in a programmatic way by IMAP :-)
>> * redundancy - if you have many ToRepository that all resist under
>>    file:/var/mail and you switch to db you have to modify all the Urls
>> * safety - custom code can modify only the logical name 
>
> db / dbfile / file are already logical mount points.
> I don't like it too much because we use this logical mountpoints for
> different contents (mailrepository/spoolrepository/generic db access).
>
> I think we should simply rewrite our repository store to provide a
> single url type for every type of object available, like a virtual
> file system.
>
> What I expect is something like spool://some/path, message://some/path.
> Then in the store we really define what specific implementation we
> want to mount in every single mount point.

+1 That sounds really intressting .. I had something simalar in mind ,
but never thought enough about it to make some clear statements.
>
> I think this would be something in the middle between what we
> currently have and what you try to achieve with the "#some.path"
> logical name.
>
> I also like more the use of the "#some.path" instead of
> "message://some/path" because I think this make less confusion not
> using something similar to real file system paths.
>
> This idea already appeared here:
> http://wiki.apache.org/james/JamesV3/Plans ("Message repository
> directory structure")
>
> And maybe I already talked about this in past.
>
> <messagestore class="VirtualStore">
>   <repository mountpoint="#some" class="TorqueMessageRepository">
>     <tablename>foo</tablename>
>   </repository>
>   <repository mountpoint="#other" class="FileMessageRepository">
>     <filepath>%{app.root}/var/mount</filepath>
>   </repository>
>   <!-- this is even more advanced because "nested" would be a file
> repository with the torque repository parent -->
>   <repository mountpoint="#some.nested" class="FileMessageRepository">
>     <filepath>%{app.root}/var/nested</filepath>
>   </repository>
> </messagestore>
>
> or alternatively something like:
>
> <messagestore class="VirtualStore">
>   <repository mountpoint="#some" class="VirtualStore>
>     <!-- default repository for this virtual store -->
>     <repository class="TorqueMessageRepository">
>       <tablename>foo</tablename>
>     </repository>
>     <repository mountpoint="nested" class="FileMessageRepository">
>       <filepath>%{app.root}/var/nested</filepath>
>     </repository>
>   </repository>
>   <repository mountpoint="#other" class="FileMessageRepository">
>     <filepath>%{app.root}/var/mount</filepath>
>   </repository>
> </messagestore>
>
> Every message repository simply have to implement a method where the
> repository itself is created with a parameter that indicate the
> relative path between the mountpoint and the real path requested: as
> an example if I ask #some.nested.foo.bar the VirtualStore
> implementation will be called with #some.nested.foo.bar. From an
> internal lookup it will find #some.nested is the most specific mount
> point and will delegate to FileMessageRepository that will be called
> with ".foo.bar" as a detail on the specific repository requested.
>
> Does this make sense?
> Imho this is much more easy than what we have now, and even more
> powerful. Today if you want to move from file to db repositories you
> have to change a lot of configurations. After this new feature the
> change would need a single edit in the config file.
Yes thats make sense.. of course.. And it whould maybe really simplify
configuration of james..
>
> Now that I wrote all of this, I understand that probably this is what
> you are proposing, with the difference that you probably would have
> used something like this:
>
> <messagestore class="VirtualStore">
>   <repository mountpoint="#some" repositoryUrl="db://maildb/foo" />
>   <repository mountpoint="#other" repositoryUrl="file://var/mount" />
>   <repository mountpoint="#some.nested"
> repositoryUrl="file://var/nested" />
> </messagestore>
>
> This way you would still use the current mailstore to retrieve each
> repository. It is simply one more layer (that I tried to merge to the
> current one)
>
> Did I understand your proposal? Is my "simplified proposal" acceptable?
>
> If all of this is ok, how would you manage the retrieval of a "child"
> repository? Adding ".child" to the logical name and retrieving it from
> the store? Or alternatively adding a getChild("child") method to the
> repository (mailboxsession) interface?
>
> Stefano
>
>

bye
Norman



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


Re: BasicMailboxSession (aka MessageRepository)

Posted by Joachim Draeger <jd...@gmx.de>.
Am Samstag, den 28.10.2006, 18:07 +0100 schrieb Danny Angus: 
> On 10/28/06, Joachim Draeger <jd...@gmx.de> wrote:
> 
> > Okay there is one point that is a bit more difficult:
> > ToRepository Mailet, which accepts a url.
> > It is used for mail that is not delivered to a user like spam or mail
> > that can't be delivered.
> > I guess the ability to put this repositories where ever one wants is
> > quite popular.
> 
> Yes very.
> I think that your idea for easy access is OK but it shouldn't replace
> URL access.
> URL access is vital for people who want James to create distinct
> repositories for filtered or copied mail (e.g. archiving). filtering
> by user is only one (important) way in which people using james want
> to sort mail.

Is the flexibility of URL access lost when there is a mapping in
between?
A logical name can be constructed the same way a URL can. 

Okay there might be a use case where the position on the filesystem/db 
has to be completely free determined from an external source / at run
time.
We could still provide the ability to use a URL. Maybe with limited
features. 

> > Maybe we could use a logical #system name space here like #system.spam
> > or #system.address-error.
> > For example this could be mapped like: #system.* -> file:/var/mail/*
> 
> Yuk, whats wrong with file:/var/mail if thats really where you want to put it??

Why does linux mount different filesystems into one logical root
filesystem?

(The idea was #system.spam becomes translated to file:/var/mail/spam)

Benefits of logical names:

* dealing with hierarchy, Quota and ACLs
* they could be accessed in a programmatic way by IMAP :-)
* redundancy - if you have many ToRepository that all resist under
   file:/var/mail and you switch to db you have to modify all the Urls
* safety - custom code can modify only the logical name 

> Plus the db URL will actually create the tables for you if it needs
> to, how great is *that*?

The table could still be created when a logical name is mapped to a
URL. 

> James has always been intended to be highly flexible, you can
> configure it in infinite different ways. I will always be nervous of
> replacing open-ended flexibility with functionality which only applies
> to specific use-cases. What you are proposing assumes that people will
> always want to use James the way you think they do now. This isn't
> true.

No, I'm not proposing replacing flexibility. Just hiding complexity. 

Well, I guess the problem is that I personally don't even have much
experience how it is used now. So I need your help here!

Joachim



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


Re: BasicMailboxSession (aka MessageRepository)

Posted by Danny Angus <da...@gmail.com>.
On 10/28/06, Joachim Draeger <jd...@gmx.de> wrote:

> Okay there is one point that is a bit more difficult:
> ToRepository Mailet, which accepts a url.
> It is used for mail that is not delivered to a user like spam or mail
> that can't be delivered.
> I guess the ability to put this repositories where ever one wants is
> quite popular.

Yes very.
I think that your idea for easy access is OK but it shouldn't replace
URL access.
URL access is vital for people who want James to create distinct
repositories for filtered or copied mail (e.g. archiving). filtering
by user is only one (important) way in which people using james want
to sort mail.

> Maybe we could use a logical #system name space here like #system.spam
> or #system.address-error.
> For example this could be mapped like: #system.* -> file:/var/mail/*

Yuk, whats wrong with file:/var/mail if thats really where you want to put it??

Plus the db URL will actually create the tables for you if it needs
to, how great is *that*?

d.

> What do you think?

I think you could make a case for making access to user inboxes
simpler, but not for replacing URL's, they are truly one of James'
nicest features.

James has always been intended to be highly flexible, you can
configure it in infinite different ways. I will always be nervous of
replacing open-ended flexibility with functionality which only applies
to specific use-cases. What you are proposing assumes that people will
always want to use James the way you think they do now. This isn't
true.

d.

---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


Re: BasicMailboxSession (aka MessageRepository)

Posted by Joachim Draeger <jd...@joachim-draeger.de>.
Stefano Bagnara schrieb:
> Joachim Draeger wrote:
>> interface MailboxService {
>>   BasicMailboxSession getBasicInboxSession(User user);
>>
>>   /** @param user the authorized User for checking credentials       
>> @param mailboxName a logical/hierarchical mailbox name **/
>>   BasicMailboxSession getBasicMailboxSession(
>>        User user, String mailboxName);
>>
>> }
>
> What about isolating the "User => Inbox Repository" association to a 
> separate service?
>
> We currently have this in the MailServer interface: "MailRepository 
> getUserInbox(String userName);" and this service is currently needed 
> by LocalDelivery and by POP3Server.
>
> I think that if we want to "move" this service to some other existing 
> service it would be better to put this in the UsersRepository 
> interface than in a repository related service. 
IMO it doesn't make sense to put it into the UsersRepository because  
its a factory method that has to return different implementations for 
different kind of backends. Choosing the right implementation is the job 
of the MailboxService.

> Maybe the best thing would be to add it to the UsersRepository but to 
> make it return the URL of the inbox repository and not the repository 
> itself.
That would make more sense to me. But I'm proposing not to use URLs.
An use case could be that the mailbox name differs from the username. 
Maybe there could be other reasons to use an individual naming scheme.
I would prefer putting this into the User object, like 
user.getInboxName(), but at the moment I don't think we need that.

>
> Cosmetic: "BasicMailboxSession" is awful for an interface name (Basic 
> make me think of a basic *implementation* of the MailboxSession 
> interface).
I know that most of my working titles are awful. :-) They are grown or 
have historic reasons.
At the end I find it difficult to choose new names. So I put out what I 
have and wait for your suggestions.
>
> Can you elaborate on the need of the 3 interfaces: BasicMailbox, 
> MailboxSession, BasicMailboxSession? Can't we start with a single 
> interface (BasicMailboxSession but renamed to something with no 
> "Basic" prefix, is my preference)
I tend to split all concerns into different interfaces at the beginning. 
Some of them get discarded, some of them get merged.
In this case the idea is that e.g. ImapMailbox and B****Mailbox ;-) 
don't inherit from SessionMailbox. directly to be able to provide one 
ImapMailbox instance and a session wrapper.
But maybe it's obsolete.

>> * sessions have to be explicitly closed. (and not weak referenced and
>> _maybe_ gc'ed away)
> +1 (you obtain a session and you release it calling its close, make 
> sense) Not sure wether the best way is to release the object to the 
> factory that produced it, or to simply "close" the object, but this is 
> a minor detail.
Thanks, I didn't think about that possibility. Maybe it enforces some 
discipline to close the session "near" to where it has been created. And 
not to close it just somewhere. Maybe it's an advantage not to have any 
session methods in the interfaces.
>> * logical mailbox names that are mapped to physical backends
> We already have something similar: we have urls that are mapped to 
> physical backends. What's the difference?
The URLs still depend on the backend. You can't browse them continuously.

>> BasicMailboxSession mailboxSession= mailboxService.
>>        getBasicMailboxSession(User.SMTP, "#system.spam");
>> mailboxSession.store(aSpamMimeMessage);
>> mailboxSession.close();      
>
> I was just thinking that we need to do some operation that is not user 
> related so I thought we needed a "getMailboxSession(String url)" 
> without User. Maybe the User.SMTP thing (virtual user) could also be 
> used.
There could also be a User.ROOT that is allowed to do any modifications, 
e.g. from the admin console.
An ACL implementation could disallow User.SMTP to deliver to a disabled 
mailbox...

> OK, but I think that 1 should include a few test in sandbox, because 
> problems with refactorings most time arise when you try to apply them.
>
I'm going to do so. It has many advantages.
> PS: thank you for taking care of this proposal. I often thought to the 
> MessageRepository issue, but I never started it because it needs time 
> to collect everyone opinion and try to achieve a result in similar 
> threads.
For me it's a mile stone for the IMAP enabled backend development. It 
wouldn't make sense to let the gap between IMAP backend and James 
backend become too big.

Joachim


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


Re: BasicMailboxSession (aka MessageRepository)

Posted by Stefano Bagnara <ap...@bago.org>.
Joachim Draeger wrote:
> Hi all!
> 
> I guess it is wished that the API for just accessing user inboxes should
> stay as easy as possible. 
> That's why I'm proposing a separate Interface that only contains core
> functionalities.
> 
> Just like addUser has been moved from James class to UsersRepository,
> getUserInbox could be moved to MailboxManagerProvider (alias
> MailboxService):
> 
> package org.apache.james.mailboxservice;
> 
> interface MailboxService {
>   BasicMailboxSession getBasicInboxSession(User user);
> 
>   /** @param user the authorized User for checking credentials 
>       @param mailboxName a logical/hierarchical mailbox name **/ 
> 
>   BasicMailboxSession getBasicMailboxSession(
>        User user, String mailboxName);
> 
> }

What about isolating the "User => Inbox Repository" association to a 
separate service?

We currently have this in the MailServer interface: "MailRepository 
getUserInbox(String userName);" and this service is currently needed by 
LocalDelivery and by POP3Server.

I think that if we want to "move" this service to some other existing 
service it would be better to put this in the UsersRepository interface 
than in a repository related service. Maybe the best thing would be to 
add it to the UsersRepository but to make it return the URL of the inbox 
repository and not the repository itself.

> interface BasicMailbox {
> 
>     /** @return the key */
>     String store(MimeMessage message) throws MessagingException;
> 
>     /** @return keys */
>     Collection list() throws MessagingException;
> 
>     MimeMessage retrieve(String key);
> 
>     /**
>      * key changes by updating
>      * @param key the current key
>      * @return the new key
>      */
>     String update(String key, MimeMessage message)
>             throws MessagingException;
> 
>     void remove(String key)
>             throws MessagingException;
> }
> 
> interface BasicMailboxSession extends BasicMailbox, MailboxSession {}
> 
> public interface MailboxSession {
>     public void close();
>     public boolean isWriteable();
> }

Cosmetic: "BasicMailboxSession" is awful for an interface name (Basic 
make me think of a basic *implementation* of the MailboxSession interface).

Can you elaborate on the need of the 3 interfaces: BasicMailbox, 
MailboxSession, BasicMailboxSession? Can't we start with a single 
interface (BasicMailboxSession but renamed to something with no "Basic" 
prefix, is my preference)

> The main differences to current MailRepository are:
> 
> * keys are generated by mailbox

+1

> * separate store/update

+1

> * sessions have to be explicitly closed. (and not weak referenced and
> _maybe_ gc'ed away)

+1 (you obtain a session and you release it calling its close, make 
sense) Not sure wether the best way is to release the object to the 
factory that produced it, or to simply "close" the object, but this is a 
minor detail.

> * logical mailbox names that are mapped to physical backends

We already have something similar: we have urls that are mapped to 
physical backends. What's the difference?
(I will elaborate on this in another leaf of this thread, currently 
evolving)

> Okay there is one point that is a bit more difficult: 
> ToRepository Mailet, which accepts a url. 
> It is used for mail that is not delivered to a user like spam or mail
> that can't be delivered.
> I guess the ability to put this repositories where ever one wants is
> quite popular.
> Maybe we could use a logical #system name space here like #system.spam
> or #system.address-error.
> For example this could be mapped like: #system.* -> file:/var/mail/*

Well, this starts fitting in a different idea we had in past: virtual 
repository tree and mount points.

> BasicMailboxSession mailboxSession= mailboxService.
>        getBasicMailboxSession(User.SMTP, "#system.spam");
> mailboxSession.store(aSpamMimeMessage);
> mailboxSession.close();      

I was just thinking that we need to do some operation that is not user 
related so I thought we needed a "getMailboxSession(String url)" without 
User. Maybe the User.SMTP thing (virtual user) could also be used.

> Roadmap:
> 
> 1. discussion
> 2. vote
> 3. deprecate MailRepository and James.getUserInbox() (not to break
> backward compatibility)
> 4. provide BasicMailbox wrappers around MailRepository 
> 5. refactor current components to use MailboxService.
> 
> What do you think?

OK, but I think that 1 should include a few test in sandbox, because 
problems with refactorings most time arise when you try to apply them.

Stefano

> Joachim

PS: thank you for taking care of this proposal. I often thought to the 
MessageRepository issue, but I never started it because it needs time to 
collect everyone opinion and try to achieve a result in similar threads.


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org