String componentName = "MyReceiver"; // The name of the receiving component.
String transformers = null; // A comma-separated list of transformers
// to apply to the result message.
String payload = "A test event"; // The payload of the event.
java.util.Map messageProperties = null; // Any properties to be associated
// with the payload.
MuleClient client = new MuleClient();
UMOMessage message = client.sendDirect(componentName,
transformers,
payload,
messageProperties);
System.out.println("Event result: " + message.getPayloadAsString());
import org.mule.umo.lifecycle.Callable;
public class EchoComponent
implements Callable
{
public Object onCall(UMOEventContext context) throws Exception
{
String msg = context.getMessageAsString();
// Print message to System.out
System.out.println("Received synchronous message: " + msg);
// Echo transformed message back to sender
return context.getTransformedMessage();
}
}
connector=org.mule.providers.vm.VMConnector
dispatcher.factory=org.mule.providers.vm.VMMessageDispatcherFactory
message.receiver=org.mule.providers.vm.VMMessageReceiver
message.adapter=org.mule.providers.vm.VMMessageAdapter
endpoint.builder=org.mule.impl.endpoint.ResourceNameEndpointBuilder
package com.jeffhanson.mule;
import org.mule.umo.FutureMessageResult;
public interface EventManager
{
/**
* Sends an event message synchronously to a given service.
*
* @param serviceName The name of the service to which the event
* message is to be sent.
* @param payload The content of the event message.
* @return Object The result, if any.
* @throws EventException on error
*/
public Object sendSynchronousEvent(String serviceName,
Object payload)
throws EventException;
/**
* Sends an event message asynchronously to a given service.
*
* @param serviceName The name of the service to which the event
* message is to be sent.
* @param payload The content of the event message.
* @return FutureMessageResult The result, if any.
* @throws EventException on error
*/
public FutureMessageResult sendAsynchronousEvent(String serviceName,
Object payload)
throws EventException;
/**
* Starts this event manager.
*/
public void start();
/**
* Stops this event manager.
*/
public void stop();
/**
* Retrieves the protocol this event manager uses.
* @return
*/
public String getProtocol();
/**
* Registers a service to receive event messages.
*
* @param serviceName The name to associate with the service.
* @param implementation Either a container reference to the service
* or a fully-qualified class name.
*/
public void registerService(String serviceName,
String implementation)
throws EventException;
/**
* Unregisters a service from receiving event messages.
*
* @param serviceName The name associated with the service to unregister.
*/
public void unregisterService(String serviceName)
throws EventException;
}
package com.jeffhanson.mule;
import org.mule.umo.*;
import org.mule.extras.client.MuleClient;
import org.mule.impl.endpoint.MuleEndpoint;
import org.mule.config.QuickConfigurationBuilder;
import java.util.HashMap;
import java.util.Map;
public class EventManagerFactory
{
private static HashMap instances = new HashMap();
/**
* Retrieves the event manager instance for a given protocol.
*
* @param protocol The protocol to use.
* @return EventManager The event manager instance.
*/
public static EventManager getInstance(String protocol)
{
EventManager instance = (EventManager)instances.get(protocol);
if (instance == null)
{
instance = new EventManagerImpl(protocol);
instances.put(protocol, instance);
}
return instance;
}
/**
* A concrete implementation for a simple event manager.
*/
private static class EventManagerImpl
implements EventManager
{
private UMOManager manager = null;
private QuickConfigurationBuilder builder = null;
private MuleClient eventClient = null;
private String protocol = null;
private MuleEndpoint receiveEndpoint = null;
private MuleEndpoint sendEndpoint = null;
private EventManagerImpl(String protocol)
{
this.protocol = protocol;
}
/**
* Starts this event manager.
*/
public void start()
{
try
{
builder = new QuickConfigurationBuilder();
manager = builder.createStartedManager(true,
protocol + "tmp/events");
eventClient = new MuleClient();
receiveEndpoint = new MuleEndpoint(protocol
+ "tmp/events/receive");
sendEndpoint = new MuleEndpoint(protocol + "tmp/events/send");
}
catch (UMOException e)
{
System.err.println(e);
}
}
/**
* Stops this event manager.
*/
public void stop()
{
try
{
manager.stop();
}
catch (UMOException e)
{
System.err.println(e);
}
}
/**
* Retrieves the protocol this event manager uses.
* @return
*/
public String getProtocol()
{
return protocol;
}
/**
* Registers a service to receive event messages.
*
* @param serviceName The name to associate with the service.
* @param implementation Either a container reference to the service
* or a fully-qualified class name
* to use as the component implementation.
*/
public void registerService(String serviceName,
String implementation)
throws EventException
{
if (!manager.getModel().isComponentRegistered(serviceName))
{
try
{
builder.registerComponent(implementation,
serviceName,
receiveEndpoint,
sendEndpoint);
}
catch (UMOException e)
{
throw new EventException(e.toString());
}
}
}
/**
* Unregisters a service from receiving event messages.
*
* @param serviceName The name associated with the service to unregister.
*/
public void unregisterService(String serviceName)
throws EventException
{
try
{
builder.unregisterComponent(serviceName);
}
catch (UMOException e)
{
throw new EventException(e.toString());
}
}
/**
* Sends an event message synchronously to a given service.
*
* @param serviceName The name of the service to which the event
* message is to be sent.
* @param payload The content of the event message
* @return Object The result, if any.
* @throws EventException on error
*/
public Object sendSynchronousEvent(String serviceName,
Object payload)
throws EventException
{
try
{
if (!manager.getModel().isComponentRegistered(serviceName))
{
throw new EventException("Service: " + serviceName
+ " is not registered.");
}
String transformers = null;
Map messageProperties = null;
UMOMessage result = eventClient.sendDirect(serviceName,
transformers,
payload,
messageProperties);
if (result == null)
{
return null;
}
return result.getPayload();
}
catch (UMOException e)
{
throw new EventException(e.toString());
}
catch (Exception e)
{
throw new EventException(e.toString());
}
}
/**
* Sends an event message asynchronously.
*
* @param serviceName The name of the service to which the event
* message is to be sent.
* @param payload The content of the event message.
* @return FutureMessageResult The result, if any
* @throws EventException on error
*/
public FutureMessageResult sendAsynchronousEvent(String serviceName,
Object payload)
throws EventException
{
FutureMessageResult result = null;
try
{
if (!manager.getModel().isComponentRegistered(serviceName))
{
throw new EventException("Service: " + serviceName
+ " is not registered.");
}
String transformers = null;
Map messageProperties = null;
result = eventClient.sendDirectAsync(serviceName,
transformers,
payload,
messageProperties);
}
catch (UMOException e)
{
throw new EventException(e.toString());
}
return result;
}
}
}
package com.jeffhanson.mule;
import java.util.Date;
public class TestService
{
public void receiveEvent(String eventMessage)
{
System.out.println("\n\nTestService.receiveEvent(String) received "
+ "event message: " + eventMessage + "\n\n");
}
public void receiveEvent(Integer eventMessage)
{
System.out.println("\n\nTestService.receiveEvent(Integer) received "
+"event message: " + eventMessage + "\n\n");
}
public void receiveEvent(Date eventMessage)
{
System.out.println("\n\nTestService.receiveEvent(Date) received "
+ "event message: " + eventMessage + "\n\n");
}
}
package com.jeffhanson.mule;
import org.apache.log4j.Logger;
import org.apache.log4j.Level;
import org.apache.log4j.BasicConfigurator;
import java.util.Date;
public class EventClient
{
static Logger logger = Logger.getLogger(EventClient.class);
public static void main(String[] args)
{
// Set up a simple configuration that logs on the console.
BasicConfigurator.configure();
logger.setLevel(Level.ALL);
try
{
EventManager eventManager =
EventManagerFactory.getInstance("vm://");
eventManager.start();
String serviceName = TestService.class.getName();
String implementation = serviceName;
eventManager.registerService(serviceName, implementation);
Object result =
eventManager.sendSynchronousEvent(serviceName, "A test message");
if (result != null)
{
System.out.println("Event result: " + result.toString());
}
result =
eventManager.sendSynchronousEvent(serviceName, new Integer(23456));
if (result != null)
{
System.out.println("Event result: " + result.toString());
}
result =
eventManager.sendSynchronousEvent(serviceName, new Date());
if (result != null)
{
System.out.println("Event result: " + result.toString());
}
eventManager.stop();
}
catch (EventException e)
{
System.err.println(e.toString());
}
}
}
我们有许多方法可以实现面向服务的架构Q无论最l目标是消除大型是简单地重用软g资。匹兹堡大学ȝ中心 (UPMC)和Starwood Hotels & Resorts Worldwide公司都有正在q行中的SOA目Q这无疑表明?jin)SOA实施q程的多h。对于这两种不同方向的工作,他们在本质上都是要徏立集中的用于存储和编制Y件资产的仓库?/p>
对于匹兹堡大学医疗中?UPMC)而言Q一个目标就是在l织内部充分利用单个SOA 开发项目的价|q同时也涉及(qing)C(jin)理问题。“我们已l做?jin)很有h(hun)值的工作Q但是在其他的领域却不能被普遍用的。”UPMC企业中间件小l的MQ Duane Falk说。“我们朝着SOA的方向发展不仅仅是ؓ(f)?jin)用它的一些技术来帮助我们解决问题Q我们也在努力朝着使资源重用性更高的方向发展。?/p>
Falk 说我们选出?jin)一些高U开发h员和架构师来讨论开始的最?jng)_炏V“普遍的意见是把某些资聚集在一hq图书馆Q在那里Z可以识别、存储、读取这些可以重用的代码和其他资源。”他说?/p>
匹兹堡大学医疗中?UPMC)正在使用匹兹堡市(jng)LogicLibrary公司提供的Logidex原数据仓库来规模的实验一个项目。Falk 说一个研发小l正与一个v外开发h员联合重构程序来理ȝ器械资?/p>
“我们已l感觉到q样做是有优势的:保在最后阶D|们把全部的代码和对象攑֜保存完好的中心位|,虽然开发中我们只用C(jin)其中的一部分Q但是放在这里我们以后可以l重用。?/p>
q个目l用Logidex来对pȝ设计、架构还有开发的其他服务q行分类。“其他小l,如企业中间gl,他们在写用于不同领域的Web服务和核心组件的代码Q而且我们希望把那些代码也攑ֈ仓库中来。”Falk说。这个仓库也可能?x)帮助UMPC理一致性问题,如Sarbanes-Oxley Act?/p>
“我们这个小实验的一个主要目的就?我们所有的开发h员都能够应用LogicLibraryQ不仅仅是我们的目可以讉KQ而且要做到其他组同样可以讉K。即使他们只有一个或者两个服务,但是他们可以获得文档记录和发表方面的l验Qƈ且这样做会(x)帮助我们军_是否l箋朝着SOA的方向前q。?/p>
记录和管理服务在Starwood Hotels & Resorts Worldwide公司也是中心论题Q这里正在进行的SOA目的目标是最大限度的消除大型机?/p>
Starwood公司是通过一pd的合q和收购建立的,其中最大的是Sheraton子公司?/p>
“那个时候,理层做出决?l箋保留Sheratonpȝq且作ؓ(f)主要的预订系l。我们终止了(jin)ZIBM技术、客L(fng)控制pȝ(CICS)以及(qing)Cobol应用E序的大型机遗留pȝQ?srael del Rio_(d)Starwood公司的技术方案和架构高副总裁?/p>
大约三年以前QStarwood公司军_朝着SOA的方向发展,q且对Linux、J2EE和IBM WebSphere实现标准化。他说。“最开始的时候,我们通过在这些^C开发新的应用程序,之后逐渐开始卸载一些大型机应用E序攑ֈ开攄l上来。这时我们也开始发展一些XML服务Q但那ƈ不是我们现在所见到的Web服务Q”他说?/p>
Del Rio?一q半之前QStarwood 公司为消除大型机l出?jin)致命一凅R“一切都围绕着SOA的概念,”他说。ƈ且没有移植的应用E序Q他补充道。“所有的一切都是通过服务从零开始编写代码、进行设计。那是巨大的工作d。?/p>
Z(jin)理不同的小l开发的服务QStarwood公司使用Systinet公司提供的Systinet注册信息表,q个公司位于ȝ的伯灵顿?“我们在注册信息表中(Registry)定义?0%?0%的服务。我们将l束C百计的服务,?del Rio说。Starwood公司目前使用Systinet来进行支配和{略理Q同时用Actional 公司的Looking Glass产品用于服务理QActional 公司位于加州的Mountain View?jng)?/p>
现在Q服务都必须和内部系l绑定在一Pdel Rio_(d)因此Starwood公司不再使用Systinet公司l一描述、发现和集成(UDDI)的功能。“但是知道他们公司有q个功能q是很好的。我们已l打把一些服务做成公共服务。?/p>
2006q的W一季度QStarwood公司开始在新系l上实现一些独立属性,然后做集成测试。“我们研I的范围是徏立在能够消除大型机的基础之上Q”他说。这是?006q底实现的目标?/p>
对于Starwood公司QSOA的道路是正确的,但是del Rio说这条\又是充满艰险的。“SOA是一个好的概c(din)我们应该朝着SOA的方向发展,管实现的过E是艰辛的。这是成熟的历E。?/p>