A web service design issue with patterns

Hello,

I抎 like to ask for your help in the following design issue:

I need to create an email sending web service (with Axis). Only just one method which returns with an integer return code. This handles the following:

-based on the given parameters gets the email addresses from an

LDAP server (with netscape ldap for java)

-makes a cache from them (only after a timeout period will be the cache

refreshed) (don抰 know what tool to use for this)

-selects html templates which to be sent based on the given parameters

-sends emails with the appropriate templates (with Velocity)

-the whole process is logged (with log4j)

I have to write the code as generic as possible. I know that some design pattern should be used for this. (some from GoF , and I know there exists design patterns specially created for web services as well).

Could you enumerate me which patterns (and for what part of the program) would be the best choice to solve this problem? I have read through some books about patterns, but don抰 have the knowledge to pick up the right one for a concrete problem like this..

Thank you in advance,

nagybaly

[1201 byte] By [o9ipa] at [2007-11-26 17:11:58]
# 1

> Hello,

>

> I抎 like to ask for your help in the following design

> issue:

>

> I need to create an email sending web service (with

> Axis). Only just one method which returns with an

> integer return code. This handles the following:

Lots of responsibilities here. You would do well to break this up into several classes that you can test separately.

I would also advise that you not embed all this in a servlet. Make a service that collaborates with several objects to accomplish the task and let the serlvet just call it.

.> -based on the given parameters gets the email

> addresses from an

> LDAP server (with netscape ldap for java)

I'd recommend Spring's LDAP module. Pretty terrific stuff.

> cache from them (only after a timeout period will be

> the cache

> refreshed) (don抰 know what tool to use for

> this)

Maybe EhCache or OsCache or something like that.

> -selects html templates which to be sent based on

> the given parameters

Where does this come from? Certainly not the LDAP. A relational database? Write a DAO for the document template.

> -sends emails with the appropriate templates (with

> Velocity)

Have an e-mail sender service using Java Mail.

> -the whole process is logged (with log4j)

Easily done.

> I have to write the code as generic as possible. I

> know that some design pattern should be used for

> this.

No pattern. There might be patterns, if you say that the DAOs to access the LDAP and RDB are patterns.

Stop thinking patterns and start thinking objects.

> (some from GoF , and I know there exists design

> patterns specially created for web services as

> well).

Nope.

> Could you enumerate me which patterns (and for what

> part of the program) would be the best choice to

> solve this problem? I have read through some books

> about patterns, but don抰 have the knowledge to pick

> up the right one for a concrete problem like this..

> Thank you in advance,

> nagybaly

You haven't read them because they aren't there. Your problem is pretty specific, even if it's common.

%

duffymoa at 2007-7-8 23:39:51 > top of Java-index,Other Topics,Patterns & OO Design...
# 2

In addition to Duffy's as always salient points, I think you have to decompose your services a bit more. You have, in my mind, three separate services: authentication, email generation and personalized email template services.

Your authentication service will accept a token (username/password in your SOAP message, or better, a ws-security compliant header) and validate the user. What will be returned will be some kind of a profile object (perhaps with the user's roles if performing authorization as well) in which an email address can also be present.

Your email template service will accept a user or profile and return the appropriate style and custom items, such as, perhaps a user signature and corporate footer/disclaimer.

Your email generation service will accept a template, an email address and the content to send. Presumably, you will then transform the message content with the message template to produce a customized email. As Duffy indicated, JavaMail can easily send this type of message.

You can of course re-juggle the pieces. The templating service could accept both a user token and the message to transform, returning a formatted message. Now, the email transport service would simply send whatever was furnished it.

In addition to all of the above, you will need components or aspects to assist in persisting the templates. Logging and auditing are normally trivial and will depend on your requirements.

I completely agree with Duffy that you cannot have 'pattern fever' when approaching this kind of problem. You can think 'top-down' from the service level, as well as 'bottom-up' from objects. Really, you do both. Best of luck!

- Saish

Saisha at 2007-7-8 23:39:51 > top of Java-index,Other Topics,Patterns & OO Design...
# 3

Thank you for all of your reply! :)

I know that some decomposition is needed but that's why I thought I need patterns because a method sendMail which I'm writing can be called with different parameters : in order to avoid some code duplication at the method overloading maybe the template pattern could be used. As the email address query from the ldap differs based on the sendMail method's parameters I thought a Strategy pattern could be used for the right selection.

And what about the server side caching of the results got from ldap? I know that Axis has some feature but not really documented

regards,

nagybaly

o9ipa at 2007-7-8 23:39:51 > top of Java-index,Other Topics,Patterns & OO Design...
# 4

> Thank you for all of your reply! :)

> I know that some decomposition is needed but that's

> why I thought I need patterns because a method

> sendMail which I'm writing can be called with

> different parameters : in order to avoid some code

> duplication at the method overloading maybe the

> template pattern could be used. As the email address

> query from the ldap differs based on the sendMail

> method's parameters I thought a Strategy pattern

> could be used for the right selection.

This is just my opinion, but rather than striving to use Memento, Visitor, Strategy, et. al., simply code it so it works. If you still have pattern fever, refactor as needed.

> And what about the server side caching of the results

> got from ldap? I know that Axis has some feature but

> not really documented

> regards,

> nagybaly

Caching is a very general term. Are you running in a cluster? Do you need failover? Does the cache get refreshed? Can users see stale cached data? I am not sure how Axis got into a caching discussion. However, you can do everything from your own home-grown, ever-too-popular Singleton read-mostly Map, or you can go for a higher-end solution such as JBoss Cache or OSCache.

- Saish

Saisha at 2007-7-8 23:39:51 > top of Java-index,Other Topics,Patterns & OO Design...
# 5

> Caching is a very general term. Are you running in a

> cluster? Do you need failover? Does the cache get

> refreshed? Can users see stale cached data? I am

> not sure how Axis got into a caching discussion.

> However, you can do everything from your own

> home-grown, ever-too-popular Singleton read-mostly

> Map, or you can go for a higher-end solution such as

> JBoss Cache or OSCache.

I have to question the caching requirement. First of all, LDAP is designed to maximize retrieval efficiency. Secondly, email is slow an asynchronous and it's not going to matter if it takes a few more seconds to send an email. It's also unlikely that people will be sending emails to large groups with such frequency that caching will do much more than use up memory (otherwise I feel sorry for the people recieving the emails.) Caching often creates more problems than it solves. If you don't strictly need it, you are better off leaving it out.

Having said that,if you must use caching, you might also want to check out EHCache.

dubwaia at 2007-7-8 23:39:51 > top of Java-index,Other Topics,Patterns & OO Design...
# 6

Hello!

Thank you for your suggestion. I don't really know too much about caching escpecially in web services.

The main purpose of caching the addresses from the ldap is to reduce the connections to ldap as much as possible. The working of it would be the following: In a Tomcat+Axis environment is a sendMail() web service call is established the service checks the memory first if the addresses have been previously cached into it. If so, then checks if it isn't beyond time out. If no, then reads out the addresses from the cache, if yes creates a new cache or or refreshes that one for which the timeout period expired.

But the main question which I don't really understand:

If I create caching (eg. with singleton) then it's sure that the addresses will be in the cache during the web service call. But if from the remote side the client closes the connection, what will happen with the cache on the server side ? Won't all resources be free up after a connection closes?

So if a next call is established is it possible for the client to get that cache which was created in a previous call?

(I'm using netscape ldap for java)

Thanks in advance,

nagybaly

o9ipa at 2007-7-8 23:39:51 > top of Java-index,Other Topics,Patterns & OO Design...
# 7

> Hello!

> Thank you for your suggestion. I don't really know

> too much about caching escpecially in web services.

> The main purpose of caching the addresses from the

> ldap is to reduce the connections to ldap as much as

> possible. The working of it would be the following:

> In a Tomcat+Axis environment is a sendMail() web

> service call is established the service checks the

> memory first if the addresses have been previously

> cached into it. If so, then checks if it isn't beyond

> time out. If no, then reads out the addresses from

> the cache, if yes creates a new cache or or refreshes

> that one for which the timeout period expired.

>

The most I would cache would be after a user authenticated for the duration of the web (or web service) session. So, a user logs in, cache the authentication credentials and give the user an encrypted cookie (this is the standard HTTP session model). When the session times out, the credentials will automatically be removed. If you are using web services instead (ala Axis), you can use ws-security or fall back on the HTTP session strategy.

> But the main question which I don't really

> understand:

>

> If I create caching (eg. with singleton) then it's

> sure that the addresses will be in the cache during

> the web service call. But if from the remote side the

> client closes the connection, what will happen with

> the cache on the server side ? Won't all resources be

> free up after a connection closes?

No, not out of the box. You would have to code that. Unless the cache is the user's HTTP session. But if you have your own Singleton, it will continue to accumulate cached (and presumably stale) data.

> So if a next call is established is it possible for

> the client to get that cache which was created in a

> previous call?

> I'm using netscape ldap for java)

> Thanks in advance,

> nagybaly

You can cache the connection to LDAP for a (slight) performance boost. You can cache the authentication credentials in the server (or client-side) state (e.g., session) for a bigger boost in performance. Beyond that, I think you risk having stale data and a bloated cache.

- Saish

Saisha at 2007-7-8 23:39:51 > top of Java-index,Other Topics,Patterns & OO Design...
# 8

> Hello!

> Thank you for your suggestion. I don't really know

> too much about caching escpecially in web services.

> The main purpose of caching the addresses from the

> ldap is to reduce the connections to ldap as much as

> possible. The working of it would be the following:

> In a Tomcat+Axis environment is a sendMail() web

> service call is established the service checks the

> memory first if the addresses have been previously

> cached into it. If so, then checks if it isn't beyond

> time out. If no, then reads out the addresses from

> the cache, if yes creates a new cache or or refreshes

> that one for which the timeout period expired.

The requirements will bascially determine whether caching makes sense. First, how long are you going to cache the data? What's the maximum acceptable time? What happens when someone doesn't get an email because the cache wasn't refreshed? How often are you expecting this service to be called?

dubwaia at 2007-7-8 23:39:51 > top of Java-index,Other Topics,Patterns & OO Design...