diff --git a/doc/reference/src/images/nms-quickstart-gui.png b/doc/reference/src/images/nms-quickstart-gui.png
new file mode 100644
index 00000000..80183783
Binary files /dev/null and b/doc/reference/src/images/nms-quickstart-gui.png differ
diff --git a/doc/reference/src/images/nms-quickstart-msg-destinations.jpg b/doc/reference/src/images/nms-quickstart-msg-destinations.jpg
new file mode 100644
index 00000000..a5131b90
Binary files /dev/null and b/doc/reference/src/images/nms-quickstart-msg-destinations.jpg differ
diff --git a/doc/reference/src/images/nms-quickstart.jpg b/doc/reference/src/images/nms-quickstart.jpg
new file mode 100644
index 00000000..37369023
Binary files /dev/null and b/doc/reference/src/images/nms-quickstart.jpg differ
diff --git a/doc/reference/src/images/nms-quickstart.pptx b/doc/reference/src/images/nms-quickstart.pptx
new file mode 100644
index 00000000..59f33f15
Binary files /dev/null and b/doc/reference/src/images/nms-quickstart.pptx differ
diff --git a/doc/reference/src/index.xml b/doc/reference/src/index.xml
index 40cc3a46..6f850218 100644
--- a/doc/reference/src/index.xml
+++ b/doc/reference/src/index.xml
@@ -45,6 +45,7 @@
+
@@ -59,7 +60,7 @@
The Spring.NET FrameworkReference DocumentationVersion 1.2.0 M1
- Last Updated July 16, 2008
+ Last Updated August 15,2008Mark
@@ -375,6 +376,9 @@
+
+
+
&quickstarts;
@@ -386,6 +390,7 @@
&tx-quickstart;
&quartz-quickstart;
&nms-quickstart;
+ &wcf-quickstart;
Spring.NET for Java developers
diff --git a/doc/reference/src/messaging.xml b/doc/reference/src/messaging.xml
index d810bc6a..e13176e9 100644
--- a/doc/reference/src/messaging.xml
+++ b/doc/reference/src/messaging.xml
@@ -189,13 +189,12 @@
higher level than the traditional messaging APIs such as JMS and NMS
since you are programing to a service interface and use metadata (either
XML or attributes) to configure the messaging behavior. If you prefer to
- use this service-oriented, RPC style approach, to messaging middleware
- then look to see if a vendor provides a WCF binding for your messaging
- provider. Note that even with the option of using WCF, many people
- prefer to sit 'closer to the metal' when using messaging middleware, to
- access specific features and functionality not available in WCF, or
- simply because they are more comfortable with that programming
- model.
+ use this service-oriented, RPC style approach, then look to see if a
+ vendor provides a WCF binding for your messaging provider. Note that
+ even with the option of using WCF, many people prefer to sit 'closer to
+ the metal' when using messaging middleware, to access specific features
+ and functionality not available in WCF, or simply because they are more
+ comfortable with that programming model.
@@ -1156,6 +1155,15 @@ namespace MyApp
An optional message selector for this
listener.
+
+
+ pubsub-domain
+
+ An optional boolean value. Set to true for the publish-subscribe domain
+ (Topics) or false (the default) for point-to-point domain (Queues). This is useful
+ when using the default implementation for destination resolvers.
+
+
@@ -1294,28 +1302,43 @@ namespace MyApp
TIBCO EMS Specific Details
- Caching of messaging resources is usually done by a wrapping the
- 'raw provider' provider implementation with an implementation that will
- cache messaging resources. The resources that are candidates for caching
- are the Connection, Session, and MessageProducer. The JMS specification
- requires that the Connection be thread safe. The Session and
- MessageProducer are not required to be thread safe but they are in TIBCO's
- implementation. The most important resource to cache is the JMS Connection
- since the flow of events in the message template class (EmsTemplate) is to
- create/close a connection on each operation and this is an expensive
- operation.
+ This section covers functionality and behavior that is different
+ than described previously and is specific to TIBCO EMS.
- Spring provides a convenience class, SingleConnectionFactory, in
- which the same Connection is returned on calls to CreateConnection() and
- all calls to .Close() on the returned Connection are ignored. Since
- TIBCO's Connection class does not have an interface nor virtual methods
- this strategy is not possible. An alternative strategy used is to
- 'hard-code' the caching of these resources within EmsTemplate and
- SimpleMessageContainer. This functionality is controlled by the property
- CacheJmsResources and is set to true by default,
- resulting in caching of Connection, Session, and MessageProducer. When
- using the TIBCO EMS binding for the NMS APIs you do not need to set this
- property and can instead use one of the wrapper implementations in Spring
- based on the NMS API that performs caching of messaging resources.
+
+ Resource Management
+
+ Caching of messaging resources is usually done by a wrapping the
+ 'raw provider' provider implementation with an implementation that will
+ cache messaging resources. The resources that are candidates for caching
+ are the Connection, Session, and MessageProducer. The JMS specification
+ requires that the Connection be thread safe. The Session and
+ MessageProducer are not required to be thread safe but they are in
+ TIBCO's implementation. The most important resource to cache is the EMS
+ Connection since the flow of events in the message template class
+ (EmsTemplate) is to create/close a connection on each operation and this
+ is an expensive operation.
+
+ Spring provides a convenience class, SingleConnectionFactory, in
+ which the same Connection is returned on calls to CreateConnection() and
+ all calls to .Close() on the returned Connection are ignored. Since
+ TIBCO's Connection class does not have an interface nor virtual methods
+ this strategy is not possible. An alternative strategy used is to
+ 'hard-code' the caching of these resources within EmsTemplate and
+ SimpleMessageContainer. This functionality is controlled by the property
+ CacheJmsResources and is set to true by default,
+ resulting in caching of Connection, Session, and MessageProducer. When
+ using the TIBCO EMS binding for the NMS APIs you do not need to set this
+ property and can instead use one of the wrapper implementations in
+ Spring based on the NMS API that performs caching of messaging
+ resources.
+
+
+
+ Queue browsing in EmsTemplate
+
+ The following queue browsing operations are available on
+ EmsTemplate
+
\ No newline at end of file
diff --git a/doc/reference/src/nms-quickstart.xml b/doc/reference/src/nms-quickstart.xml
index eb0619a4..b31ad002 100644
--- a/doc/reference/src/nms-quickstart.xml
+++ b/doc/reference/src/nms-quickstart.xml
@@ -9,19 +9,22 @@
messaging to implement a system for purchasing a stock. To purchase a
stock, a client application will send a stock request message containing
the information about the stock, i.e. ticker symbol, quantity, etc. The
- client request message will be recieved by the server where it will
- perform business processing on the requst, for example to determine if the
- user has sufficient credit to purchase the stock or if the user is even
- allowed to make the purchase due to existing account restrictions. Usually
- the server application will persist state about the request and forward it
- on to an execute venue where the actual execution of the stock request is
- peformed. In addition, market data for the stock will be sent from the
- server process to the client. The high level messaging flow is shown
- below.
+ client request message will be received by the server where it will
+ perform business processing on the request, for example to determine if
+ the user has sufficient credit to purchase the stock or if the user is
+ even allowed to make the purchase due to existing account restrictions.
+ These are typically external processes as well. Usually the server
+ application will persist state about the request and forward it on to an
+ execute venue where the actual execution of the stock request is
+ performed. In addition, market data for the stock will be sent from the
+ server process to the client. The high level exchange of information is
+ shown below.
-
-
-
+
+
+
+
+
@@ -42,9 +45,14 @@
one based on messaging or another middleware technology. The messaging
flow showing the queues and topics used is shown below.
-
+
+
+
+
+
-
+ Queues are shown in red and topics in green.
@@ -52,7 +60,7 @@
Gateways represent the service operation to send a message. The
client will send a stock request to the server based on the contract
- defined by the IStockService interface .
+ defined by the IStockService interface .
public interface IStockService
{
@@ -61,7 +69,7 @@
The server will send market data to the clients based on the
contract defined by the IMarketDataService
- interface.
+ interface.
public interface IMarketDataService
{
@@ -78,7 +86,7 @@
created. Implementations that use messaging to communicate will be based
on the Spring's NmsGateway class and will be
discussed later. stub or mock implementations can be used for testing
- purposes.
+ purposes.
@@ -113,7 +121,7 @@
Running xsd.exe on this schema will result in a class that contains
- properties for each of the element names. A parital code listing of the
+ properties for each of the element names. A partial code listing of the
TradeRequest class is shown below// This code was generated by a tool.
@@ -148,7 +156,7 @@
When sending a response back to the client the type
TradeResponse will be used. The schema for the
- TradeResponse is shown below
+ TradeResponse is shown below
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
targetNamespace="http://www.springframework.net/nms/common/2008-08-05">
@@ -202,10 +210,10 @@
- Mesage Handlers
+ Message HandlersWhen the TradeRequest message is received by
- the server, it wll be handled by the class
+ the server, it will be handled by the class
Spring.NmsQuickStart.Server.Handlers.StockAppHandler
shown below
@@ -236,6 +244,186 @@
}
}
+ The stub implementations of the services, located in the namespace
+ Spring.NmsQuickStart.Server.Services.Stubs, will result
+ in always sending back a error-free trade response message. A realistic
+ implementation would likely have the execution venue and trading service
+ be remote services and the trading service could be implemented as a local
+ transactional service layer that uses spring's declarative transaction
+ management features.
+
+ The client will receive a TradeResponse message as well as a
+ Hashtable of data representing the market data. The message handle for the
+ client is the class Spring.NmsQuickStart.Client.Handlers.StockAppHandler
+ and is shown below.
+
+ public class StockAppHandler
+ {
+
+ // definition of stockController omitted for brevity.
+
+ public void Handle(Hashtable data)
+ {
+ // forward to controller to update view
+ stockController.UpdateMarketData(data);
+ }
+
+ public void Handle(TradeResponse tradeResponse)
+ {
+ // forward to controller to update view
+ stockController.UpdateTrade(tradeResponse);
+ }
+ }
+
+ What is important to note about these handlers is that they contain
+ no messaging API artifacts. As such you can write unit and integration
+ tests against these classes independent of the middleware. The missing
+ link between the messaging world and the objects processed by the message
+ handlers are message converters. Spring's messaging helper classes, i.e.
+ SimpleMessageListenerContainer and NmsTemplate use message converters to
+ pass data to the handlers and to send data via messaging for gateway
+ implementations
+
+
+
+ Message Converters
+
+ The implementation of IMessageConverter used is
+ Spring.NmsQuickStart.Common.Converters.XmlMessageConverter.
+ This converter adds the ability to marshal and unmarshal objects to and
+ from XML strings. It also uses Spring's
+ SimpleMessageConverter to convert Hashtables,
+ strings, and byte arrays. In order to pass information about the
+ serialized type, type information is put in the message properties. The
+ type information can be either the class name or an integer value
+ identifying the type. In systems where the client and server are deployed
+ together and are tightly coupled, sharing the class name is a convenient
+ shortcut. The alternative is to register a type for a given integer value.
+ The XML configuration used to configure these objects is shown
+ below
+
+ <object name="XmlMessageConverter" type="Spring.NmsQuickStart.Common.Converters.XmlMessageConverter, Spring.NmsQuickStart.Common">
+ <property name="TypeMapper" ref="TypeMapper"/>
+ </object>
+
+ <object name="TypeMapper" type="Spring.NmsQuickStart.Common.Converters.TypeMapper, Spring.NmsQuickStart.Common">
+ <!-- use simple configuation style -->
+ <property name="DefaultNamespace" value="Spring.NmsQuickStart.Common.Data"/>
+ <property name="DefaultAssemblyName" value="Spring.NmsQuickStart.Common"/>
+ </object>
+
+ This configuration is common between the server and the
+ client.
+
+
+
+ Messaging Infrastructure
+
+ The implementations of the gateway interfaces inherit from Spring's
+ helper class NmsGatewaySupport in order to get easy
+ access to a NmsTemplate for sending. The implementation of the
+ IStockService interface is shown below
+
+ public class NmsStockServiceGateway : NmsGatewaySupport, IStockService
+ {
+ private IDestination defaultReplyToQueue;
+
+ public IDestination DefaultReplyToQueue
+ {
+ set { defaultReplyToQueue = value; }
+ }
+
+ public void Send(TradeRequest tradeRequest)
+ { // post process message
+ NmsTemplate.ConvertAndSendWithDelegate(tradeRequest, delegate(IMessage message)
+ {
+ message.NMSReplyTo = defaultReplyToQueue;
+ message.NMSCorrelationID = new Guid().ToString();
+ return message;
+ });
+ }
+ }
+
+ The use of an anonymous delegate allows makes it very easy to apply
+ any post processing logic to the converted message.
+
+ The object definition for the
+ NmsStockServiceGateway is shown below along with
+ its dependent object definitions of NmsTemplate and the
+ ConnectionFactory.
+
+ <object name="StockServiceGateway" type="Spring.NmsQuickStart.Client.Gateways.NmsStockServiceGateway, Spring.NmsQuickStart.Client">
+ <property name="NmsTemplate" ref="NmsTemplate"/>
+ <property name="DefaultReplyToQueue">
+ <object type="Apache.NMS.ActiveMQ.Commands.ActiveMQQueue, Apache.NMS.ActiveMQ">
+ <constructor-arg value="APP.STOCK.JOE"/>
+ </object>
+ </property>
+ </object>
+
+ <object name="NmsTemplate" type="Spring.Messaging.Nms.Core.NmsTemplate, Spring.Messaging.Nms">
+ <property name="ConnectionFactory" ref="ConnectionFactory"/>
+ <property name="DefaultDestinationName" value="APP.STOCK.REQUEST"/>
+ <property name="MessageConverter" ref="XmlMessageConverter"/>
+ </object>
+
+ <object id="ConnectionFactory" type="Apache.NMS.ActiveMQ.ConnectionFactory, Apache.NMS.ActiveMQ">
+ <constructor-arg index="0" value="tcp://localhost:61616"/>
+ </object>In this example the 'raw'
+ Apache.NMS.ActiveMQ.ConnectionFactory connection
+ factory was used. It would be more efficient resource wise to use Spring's
+ CachingConnectionFactory wrapper class so that
+ connections will not be open and closed for each message send as well as
+ allowing for the caching of other intermediate NMS API objects such as
+ sessions and message producers.
+
+ A similar configuration is used on the server to configure the class
+ Spring.NmsQuickStart.Server.Gateways.MarketDataServiceGateway
+ that implements the IMarketDataService
+ interface.
+
+ Since the client is also a consumer of messages, on the topic
+ APP.STOCK.MARKETDATA and the queue APP.STOCK.JOE (for Trader Joe!), two
+ message listener containers are defined as shown below.
+
+ <nms:listener-container connection-factory="ConnectionFactory">
+ <nms:listener ref="MessageListenerAdapter" destination="APP.STOCK.JOE" />
+ <nms:listener ref="MessageListenerAdapter" destination="APP.STOCK.MARKETDATA" pubsub-domain="true"/>
+ </nms:listener-container>
+
+ Refer to the messages reference
+ docs for all the available attributes to configure the container
+ and also the section on registering the NMS schema
+ with Spring..
+
+ On the server we define a message listener container for the queue
+ APP.STOCK.REQUEST but set the concurrency property to 10 so that 10
+ threads will be consuming messages from the queue.
+
+ <nms:listener-container connection-factory="ConnectionFactory" concurrency="10">
+ <nms:listener ref="MessageListenerAdapter" destination="APP.STOCK.REQUEST" />
+ </nms:listener-container>
+
+
+
+ Running the application
+
+ To run both the client and server make sure that you select
+ 'Multiple Startup Projects' within VS.NET. The GUI has a button to make a
+ hardcoded trade request and show confirmation in a text box. A text area
+ is used to display the market data. There is a 'Get Portfolio' button that
+ is not implemented at the moment. A picture of the GUI after it has been
+ running for a while and trade has been sent and responded to is shown
+ below
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/doc/reference/src/quartz-quickstart.xml b/doc/reference/src/quartz-quickstart.xml
index 757872c0..71f94e66 100644
--- a/doc/reference/src/quartz-quickstart.xml
+++ b/doc/reference/src/quartz-quickstart.xml
@@ -24,9 +24,9 @@
IJob interface represents the task you would like
to execute. You either directly implement Quartz's
IJob interface or a convenience base class. The
- Quartz ITrigger controls when a job is executed,
- for example in the wee hours of the morning every weekday (This would be
- done using Quartz's CronTrigger implementation.)
+ Quartz Trigger controls when a job is executed, for
+ example in the wee hours of the morning every weekday . This would be done
+ using Quartz's CronTrigger implementation.
Instances of your job are created every time the trigger fires. As such,
in order to pass information between different job instances you stash
data away in a hashtable that gets passed to the each Job instance upon
@@ -90,7 +90,7 @@
<object name="exampleJob" type="Spring.Scheduling.Quartz.JobDetailObject, Spring.Scheduling.Quartz">
<property name="JobType" value="Spring.Scheduling.Quartz.Example.ExampleJob, Spring.Scheduling.Quartz.Example" />
- <!-- We can inject values throgh JobDataMap -->
+ <!-- We can inject values through JobDataMap -->
<property name="JobDataAsMap">
<dictionary>
<entry key="UserName" value="Alexandre" />
@@ -103,7 +103,7 @@
JobDataAsMap, is used to set the values of the
ExampleJob's properties. This will result in the ExampleJob being
instantiated with it's UserName property value set to 'Alexandre' the
- first time the trigger fires.
+ first time the trigger fires.
We then will schedule this job to be executed on 20 second
increments of every minute as shown below using Spring's
@@ -174,9 +174,12 @@
</object>
- Note that AdminSerivce object is configured
+ Note that AdminService object is configured
using Spring as you would do normally, without consideration for Quartz.
- The trigger associated with the jobDetail object is listed below
+ The trigger associated with the jobDetail object is listed below. Also
+ note that when using MethodInvokingJobDetailFactoryObject you can't use
+ database persistence for Jobs. See the class documentation for additional
+ details. <object id="simpleTrigger" type="Spring.Scheduling.Quartz.SimpleTriggerObject, Spring.Scheduling.Quartz">
<!-- see the example of method invoking job above -->
diff --git a/doc/reference/src/scheduling.xml b/doc/reference/src/scheduling.xml
index d722472d..fcff4090 100644
--- a/doc/reference/src/scheduling.xml
+++ b/doc/reference/src/scheduling.xml
@@ -140,7 +140,11 @@ public class ExampleJob extends QuartzJobObject {
- By default, jobs will run in a concurrent fashion.
+ By default, jobs will run in a concurrent fashion.
+
+ Also note that when using MethodInvokingJobDetailFactoryObject
+ you can't use database persistence for Jobs. See the class
+ documentation for additional details.
diff --git a/doc/reference/src/wcf.xml b/doc/reference/src/wcf.xml
index e067ac72..3dc02212 100644
--- a/doc/reference/src/wcf.xml
+++ b/doc/reference/src/wcf.xml
@@ -7,7 +7,7 @@
Spring's WCF support allows you to configure your WCF services via
dependency injection and add additional behavior to them using
- Aspect-Oriented programming (AOP).
+ Aspect-Oriented programming (AOP).
There are two approaches in the 1.2 M1 release for configuring your
services with DI which are discussed in the following sections. One
@@ -26,7 +26,7 @@
the WcfQuickStart application in the examples directory.
-
+ Configuring WCF services via Dependency InjectionIn this approach the container will creates an implementation of
@@ -34,7 +34,7 @@
instance of your service type from the Spring container. This dynamic
proxy is then the final service type that is hosted.
-
+ Dependency Injection using dynamic proxiesIn this approach you develop your WCF services as you would
@@ -161,10 +161,13 @@
There are not many disadvantages to this approach other than the
need to specify the service name as the name of the object definition in
the Spring container and to ensure that singleton=false is used in the
- object definition.
+ object definition. You can also use
+ Spring.ServiceModel.Activation.ServiceHostFactory
+ to host your service inside IIS but should still refer to the service by
+ the name of the object in the Spring container.
-
+ Dependency Injection using WCF extensibility points.The second approach uses the extensibility points in WCF itself to
@@ -177,18 +180,18 @@
and
System.ServiceModel.Description.IServiceBehavior
are used to integrate Spring directly into the instancing of WCF
- services.
+ services.
Spring's implementation of
IInstanceProvider is
- Spring.ServiceModel.Dispatcher.SpringInstanceProvider.
+ Spring.ServiceModel.Support.SpringInstanceProvider.
This implementation will look for an object by type in the Spring
container and retrieve an instance configured using DI. If there is more
than one object of the type registered with the container than an
exception will be thrown. The
SpringInstanceProvider is used by a custom
service behavior class,
- Spring.ServiceModel.Dispatcher.SpringServiceBehavior
+ Spring.ServiceModel.Support.SpringServiceBehavior
where it is applied to all the service endpoints. This behavior is then
added to the custom service host
Spring.ServiceModel.Activation.SpringServiceHost
@@ -196,7 +199,7 @@
The service type is used to locate the object in the container. In
your .svc file you specify the custom service host type and also the
type of the service. Here is an example taken from the WcfQuickStart
- application that shows the use of this approach inside IIS.
+ application that shows the use of this approach inside IIS.
<%@ ServiceHost Language="C#" Debug="true" Service="Spring.WcfQuickStart.CalculatorService"
Factory="Spring.ServiceModel.Activation.ServiceHostFactory" %>
@@ -282,5 +285,9 @@
This will be shortened using a custom namespce in the 1.2 RC1
release
+
+ The value 'serverAppCalculatorEndpoint' refers to the name of an
+ enpoints in the <client> section of the standard WCF configuration
+ inside of App.config.
\ No newline at end of file
diff --git a/doc/reference/src/xsd-configuration.xml b/doc/reference/src/xsd-configuration.xml
index ae35b933..78f1624b 100644
--- a/doc/reference/src/xsd-configuration.xml
+++ b/doc/reference/src/xsd-configuration.xml
@@ -258,7 +258,7 @@
</configuration>
-
+ The nms messaging schemaThe nms tags are for use when you want to