Let us start with a need
Given a user name, userid and an email address create a user. We can call this "createUser" transaction with three parameters name, id, and email.
Let us see how a client can invoke this horizontally
Conceptual horizontal invocation using key value pairs
client -> calls -> execTransaction(requestName="createUser",name="", id="", email="")
For example this is how a web browser will invoke a transaction. The equivalnet programmatic invocation will be
SomeClass.createUser(name, id, email);
Let us see how we can provide an implementation using horizontal parts
request.createUser.classname=com.ai.db.DBRequestExecutor2
request.createUser.db=database-name
request.createUser.stmt=\
insert into user_table values({name.quote},{id.quote},{email.quote})
Purrists will quickly point out that CreateUser can be more complex. Well Horizontal parts can still solve the problem pretty decently a good number of times. Let us attempt it.
request.createUser.classname=com.ai.db.MultiExec
request.createUser.db=database-name
request.createUser.query_type=update
request.createUser.request.1=VerifyDuplicateId
request.createUser.request.2=AsyncSendVerificationEmail
request.createUser.request.3=InsertUser
request.InsertUser.classname=com.ai.db.DBRequestExecutor2
request.InsertUser.stmt=\
insert into user_table values({name.quote},{id.quote},{email.quote},'N')
So we used a transactional pipeline to do the job
Let use solve it using a vertical part
Unconvinced purists still nod their heads horizontally. So we now proceed to solve the problem using an unfettered java class
package com.mypkg;
public class CreateUser extends AbstractCreateUser
{
void createUser(String name, String id, String email)
throws RequestExecutionException
{
//write code to hearts content
}
}
Now change the config file to
request.createUser.classname=com.mypkg.CreateUser
No addtional configuration entries are required
How can we run CreateUser on a remote computer?
request.application-factory.classname=com.pkg.DelegateEnabledFactory
request.application-factory.delegates=RemoteDelegate
request.RemoteDelegate.className=com.pkg.RemoteFactoryDelegate
request.RemoteDelegate.requestNames=CreateUser,AnotherRequest,etc
request.RemoteDeleget.remote-http-url=http://www.someothermachine.com/webapp
The magic of invoking the transaction is carried out by an implementation of IFactory. So the factory itself is bootstrapped using its own features allowing us to replace various implementations for it. We can go from a simple factory to filtered factory to IOCFactory to a DelegateEnabledFactory. Assuming we are using the last this is what it does. It checks to see if there are any delegates that can handle the "CreateUser", if there is it hands over the request to them. In this case there is a delegate called "RemoteDelegate" that is configured to handle "CreateUser". That is how "CreateUser" is transferred to a remote machine. If we don't want this, just delete the "createuser" from that delegate's list.
Why is this tier-less computing
Because by flipping a switch we are able to run CreateUser on a different box other than the local. Development can take place with this switch set to local and deployment can use static or dynamic strategies to deploy these components
References
1. General Introduction to other Server side Patterns in this series