Spring 3.0.4 is now available
Posted by Helena Edelson on 21st August 2010
Spring 3.0.4 is now available: vew Arjen’s post
Posted in Java, Spring | No Comments »
Posted by Helena Edelson on 21st August 2010
Spring 3.0.4 is now available: vew Arjen’s post
Posted in Java, Spring | No Comments »
Posted by Helena Edelson on 2nd August 2010
The Maven central style artifacts are available in maven.springframework.org/milestone:
Posted in Java | No Comments »
Posted by Helena Edelson on 9th May 2010
If I had more time I would add a few new posts on esper and rabbitmq for messaging in the cloud but I just got home from 2 weeks of coast-to-coast consulting and technology presentations. Pretty exhausting. I hope to have time to post on these and a few other fun technologies. I’ve got some code samples and tests I might post with that, plus some cools stuff on esper queries with Spring Integration.
Posted in Concurrency, Erlang, Java, Messaging, RabbitMQ | No Comments »
Posted by Helena Edelson on 14th April 2010
I’ve been traveling a lot as a Senior Consultant with SpringSource and many of the engineers that have been at my private and public engagements on core spring and enterprise integration with spring have requested a copy of my sample app that I use to demonstrate configurations, run demos and tests, etc.
This week I’m finally getting it finished and available to check out from svn. I’ve had a project set up in one of our public-facing repositories, the code will be available next week. Shoot me an email via my SpringSource address – attendees have that email, or find me on linkedin.com
May 10 I officially move into engineering!
Posted in Java | No Comments »
Posted by Helena Edelson on 13th March 2010
Being a total nube at it, I didn’t realize it was as simple as downloading the GIT installer and running it. Since I’m not into doodleware (i.e. using a ui) I was cloning a GIT repos in seconds.
This is a good guide to simply generating ssh keys: http://help.github.com/mac-key-setup
Posted in Java | No Comments »
Posted by Helena Edelson on 27th January 2010
This post is merely meant as a starting guide to tinkering for a light-weight solution to handing off execution of a task for async processing without the overhead of Spring Batch or Spring JMS and Message Brokers, among other middleware solutions.
1. I have a simplistic junit test that merely kicks off the service method to view the path of execution:
/**
* TaskTests
*
* @author Helena Edelson
* @since v 1.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:infrastructure-context.xml"})
public class TaskTests extends BaseTest {
protected static final Logger logger = Logger.getLogger(TaskTests.class);
@Autowired private OrderService orderService;
@Test
public void testExecution(){
logger.debug("Starting execution thread...");
orderService.dispatch(new Order());
}
}
2. A simple context config:
<?xml version=”1.0″ encoding=”UTF-8″?>
<beans xmlns=”http://www.springframework.org/schema/beans”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xmlns:context=”http://www.springframework.org/schema/context”
xmlns:task=”http://www.springframework.org/schema/task”
xmlns:aop=”http://www.springframework.org/schema/aop”
xmlns:p=”http://www.springframework.org/schema/p”
xsi:schemaLocation=”
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd”>
<bean id=”taskExecutor” class=”org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor” p:corePoolSize=”5″ p:maxPoolSize=”25″/>
<!– OR alternately: Creates a org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor –>
<task:executor id=”taskExecutor” pool-size=”5-25″ queue-capacity=”100″ rejection-policy=”CALLER_RUNS”/>
</beans>
3. OrderService that delegates to the ThreadPoolTaskExecutor:
/**
* OrderServiceImpl is used for both orders and returns
*
* @author Helena Edelson
* @MessageEndpoint which is a @Component
* @since Dec 29, 2009
*/
@Service("orderService")
public class OrderServiceImpl implements OrderService {
private OrderDao orderDao;
private MerchantService merchantService;
private ReceivingService receivingService;
@Autowired private TaskExecutor taskExecutor;
@Autowired
public OrderServiceImpl(OrderDao orderDao, ReceivingService receivingService, MerchantService merchantService) {
this.orderDao = orderDao;
this.receivingService = receivingService;
this.merchantService = merchantService;
}
public final void dispatch(final Order order) {
logger.debug("Starting dispatch execution...");
if (this.taskExecutor != null) {
this.taskExecutor.execute(new Runnable() {
public void run() {
executorAsync(order);
}
});
}
logger.debug("Completed dispatch execution...");
}
private final void executorAsync(final Order order) {
logger.debug("Starting Async execution...");
daoDatasourceOne.createOrder(order);
daoDatasourceTwo.createOrder(order);
logger.debug("Completed Async execution...");
}
/* Where the output will be: Note the dispatch method returns control to its caller before the async method begins:
2010-01-27 13:23:27,546 [main] DEBUG org.springsource.oms.infrastructure.TaskTests - Starting execution thread...
2010-01-27 13:23:27,546 [main] DEBUG org.springsource.oms.domain.services.OrderServiceImpl - Starting dispatch execution...
2010-01-27 13:23:27,546 [main] DEBUG org.springsource.oms.domain.services.OrderServiceImpl - Completed dispatch execution...
2010-01-27 13:23:27,546 [taskExecutor-1] DEBUG org.springsource.oms.domain.services.OrderServiceImpl - Starting Async execution...
persisting org.springsource.oms.domain.entities.Order@1f10a67
*/
/**
* Alternately for a different scenario you can play around with this:
*/
public void withExecutor(final Order order) {
try {
CompletionService
I recommend looking into the @Async annotation, which I will post on shortly. In the meantime here is the ref page for Spring Task and Scheduling: http://static.springsource.org/spring/docs/3.0.x/reference/html/scheduling.html
Posted in Annotations, Concurrency, Java, Spring, Spring Task | No Comments »
Posted by Helena Edelson on 20th January 2010
If you have Maven installed:
If you are familiar with Enterprise Integration Patterns, here are some of the patterns implemented in each sample:
| Pattern / Sample | Event Driven Consumer | Polling Consumer | Message Filter | Message Translator | Content Based Router | Splitter | Aggregator | Channel Adapter | Messaging Gateway | Service Activator | Request/Reply |
| cafe | X | X | X | X | X | X | X | X | |||
| filecopy | X | X | X | X | |||||||
| errorhandling | X | X | X | X | |||||||
| helloworld | X | X | |||||||||
| jms | X | X | X | X | X | ||||||
| oddeven | X | X | X | X | X | ||||||
| quote | X | X | X | ||||||||
| ws | X | X | X | X | |||||||
| xml | X | X | X | X | X | X |
From Mark Fisher’s Post:
*NOTE: All of the samples feature certain common patterns that are essential to the underlying Spring Integration core:
Posted in Java | No Comments »
Posted by Helena Edelson on 31st December 2009
Posted in Configuration Management, Java, Software Development, Spring, Spring ROO | No Comments »
Posted by Helena Edelson on 22nd December 2009
![]() Pure Master Slave Simplified Topology |
I am not actually going to go into Broker topologies, there are many great resources for that such as this by Bruce Snyder: http://www.slideshare.net/bruce.snyder/messaging-with-activemq-presentation or http://activemq.apache.org/topologies.html, all great stuff. This example uses a store and forward topology, or, distributed queues, and incorporates basic authentication:
My use case was to handle down JMS Servers. What I needed to do was implement failover as well as master slave strategies and a topology for message redundancy in case of hardware failure, etc. The client could not have any message loss. With failover, you can see how ActiveMQ switches from the main broker to the second, third, etc on failure. I have a case of four JMS servers in production, each server it is on is load balanced. There are just a few configurations to add or modify in order to set up JMS Failover with Master/Slave for your broker topology. Here is a basic configuration. For this use case, all JMS servers are configured as standalone versus embedded. |
You will need to add the Failover protocol, either with a basic URI pattern or a composite. In this use case, there are load balanced servers in Production and multiple Development and QA environments which require different configurations for master/slave and failover.
In your application’s properties file for messaging add a modified version of this with your mappings:
activemq.broker.uri=failover://(tcp://localhost:61616,tcp://slaveh2:61616,tcp://master2:61616,tcp://slave2:61616,network:static://(tcp://localhost:61616,tcp://master2:61616,tcp://slave2:61616))?randomize=false
Note: I set connections as locked down (static) communication configurations vs multicast or dynamic discovery so that I know exactly what servers can communicate with each other and how. Also this is assuming you have one set per environment to account for mapping the appropriate IP’s in development, qa, production, dr, etc.
Note: Do not configure networkConnections for master slave, they are handled on the slave with the following configuration:
<masterConnector remoteURI= "tcp://masterhost:61616" userName="wooty" password="woo"/>
<bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory"
destroy-method="stop">
<property name="connectionFactory">
<bean class="org.apache.activemq.spring.ActiveMQConnectionFactory">
<constructor-arg value="${amq.broker.uri}"/>
<property name="userName" value="${activemq.username}"/>
<property name="password" value="${activemq.password}"/>
</bean>
</property
</bean>
<broker brokerName="{hostname}" waitForSlave="true" xmlns="http://activemq.apache.org/schema/core" dataDirectory="${activemq.base}/data">
<networkConnectors>
<!-- passed in by the client broker URI so you can easily manager per environment: sweet -->
</networkConnectors>
<transportConnectors>
<!-- TCP uses the OpenWire marshaling protocol to convert messages to stream of bytes (and back) -->
<transportConnector name="tcp" uri="tcp://localhost:61616?trace=true" />
<transportConnector name="nio" uri="nio://localhost:61618?trace=true" />
<!-- <transportConnector name="ssl" uri="ssl://localhost:61617"/>
<transportConnector name="http" uri="http://localhost:61613"/
<transportConnector name="https" uri="https://localhost:61222"/> -->
<transportConnectors>
</transportConnectors><!-- Basic security and credentials -->
<plugins>
<simpleAuthenticationPlugin>
<users>
<authenticationUser username="system" password="manager" groups="admin, publishers,consumers"/>
</users>
</simpleAuthenticationPlugin>
</plugins>
..more configuration
</broker>
<broker brokerName="{hostname}Slave" deleteAllMessagesOnStartup="true" xmlns="http://activemq.apache.org/schema/core">
<transportConnectors>
<transportConnector uri="tcp://localhost:61616"/>
</transportConnectors>
<services>
<masterConnector remoteURI= "tcp://masterhost:62001" userName="wooty" password="woo"/
</services>
<!-- Basic security and credentials -->
<plugins>
<simpleAuthenticationPlugin>
<users>
<authenticationUser username="system" password="manager" groups="admin, publishers,consumers"/>
</users>
</simpleAuthenticationPlugin>
</plugins>
</broker>
Posted in ActiveMQ, JMS, JMS Broker, Java, Messaging, Spring JMS | No Comments »
Posted by Helena Edelson on 28th November 2009
<project>
…
<build>
<finalName>${groupId}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
…
</project>
Posted in Java, Maven | No Comments »
Posted by Helena Edelson on 22nd October 2009
Tuesday I went to Ben Alex’s presentation at SpringOne on Roo. He literally build a basic but pretty comprehensive web application in ten minutes and walked us through it. I’ll write some more about it soon but the main project site is
springsource.org/roo, which pretty much says it all
Posted in Java, Software Development, Spring, Spring ROO | No Comments »
Posted by Helena Edelson on 21st October 2009
I was asked a question by a Spring student of mine and as it pertains to Spring Transaction Management, as well as transaction management and databases in general I thought I’d share it with everyone if it may help anyone else. The question went something like this:
How do we prevent concurrent modification of the same data? Two users are in the middle of a transaction on the same data. How do we isolate those operations so that other transactions can not read the data and how to we handle synchronizing changes to that data with commits? This deals with preserving data integrity, the underlying locking mechanisms of your database, transaction demarcation and transaction isolation settings which are configurable by Spring Transaction Management but ultimately controlled by your specific database vendor’s implementation.
Some ways to think about transaction isolation are:
So how do we keep one transaction from seeing uncommitted writes from other transactions and synchronize those writes?
Remember ACID = Atomicity, Consistency, Isolation and Durability?
The SQL standard defines four levels of transaction isolation in terms of three phenomena that must be prevented between concurrent transactions. These phenomena are:
For most databases, the default transaction isolation level is “read committed” (your transaction operates on the data that it sees at the beginning of the transaction). You can, for example, configure transactions to be serializable which increases lock contention, but is more suited for critical operations. Here we could get into database locking, predicate locking, etc. While it is outside the scope of this post, it is very worthwhile to know; I do suggest reading up on it.
In the java layer, here are the standard isolation levels defined in the JDBC specification, in order of weakest to strongest isolation, with the respective inverse correlation on performance:
• TRANSACTION_NONE: transactions are not supported.
• TRANSACTION_READ_UNCOMMITTED: dirty reads, non-repeatable reads and phantom reads can occur.
• TRANSACTION_READ_COMMITTED: dirty reads are prevented; non-repeatable reads and phantom reads can occur.
• TRANSACTION_REPEATABLE_READ: reads and non-repeatable reads are prevented; phantom reads can occur.
• TRANSACTION_SERIALIZABLE: dirty reads, non-repeatable reads and phantom reads are prevented.
Spring’s Transaction Management Isolation levels:
ISOLATION_DEFAULT
Use the default isolation level of the underlying datastore.
ISOLATION_READ_COMMITTED
Indicates that dirty reads are prevented; non-repeatable reads and phantom reads can occur. This level only prohibits a transaction from reading a row with uncommitted changes in it.
ISOLATION_REPEATABLE_READ
Indicates that dirty reads and non-repeatable reads are prevented; phantom reads can occur. This level prohibits a transaction from reading a row with uncommitted changes in it, and it also prohibits the situation where one transaction reads a row, a second transaction alters the row, and the first transaction rereads the row, getting different values the second time (a “non-repeatable read”).
ISOLATION_SERIALIZABLE
Indicates that dirty reads, non-repeatable reads and phantom reads are prevented. This level includes the prohibitions in ISOLATION_REPEATABLE_READ and further prohibits the situation where one transaction reads all rows that satisfy a WHERE condition, a second transaction inserts a row that satisfies that WHERE condition, and the first transaction rereads for the same condition, retrieving the additional “phantom” row in the second read.
Note the Spring isolation and JDBC isolation levels are the same.
So for XML configuration of transaction demarcation in Spring:
<tx:advice id=”txAdvice” transaction-manager=”transactionManager”>
<tx:attributes>
<tx:method name=”insert*” read-only=”false” propagation=”REQUIRED” isolation=”READ_COMMITTED”/>
</tx:attributes>
</tx:advice>
And for Annotation configuration:
in xml: <tx:annotation-driven/> to enable @Transactional
in your service layer, on the class or method level:
@Transactional
public class DefaultFooService implements FooService { ...}
@Transactional(isolation = Isolation.SERIALIZABLE)
pubic void createSomething(..){ ... }
Posted in AOP, Java, Spring, Transaction Management | No Comments »
Posted by Helena Edelson on 12th October 2009
I have been doing some research, prototyping, and am pretty excited about Compass integration with Spring. Compass simplifies search functionality and is built on top of Lucene as a search engine abstraction which extends Lucene and adds transactional support on top of it. Working with it is similar to working with DAO patterns and calls and all of Lucene’s functionality is available through Compass.
Some of the main objects are the CompassSearchSession, CompassConfiguration, CompassSession, and CompassTransaction. There is full tx rollback support, callbacks, you can easily abstract it into your application’s framework to make calls incredibly simple, and if you are familiar with Spring it is one step away from dao work. Very clean, very simple. I will post some framework abstraction code this week.
Posted in Java, Search, Spring | No Comments »
Posted by Helena Edelson on 4th October 2009
The importance of decoupling in applications is vital but it is not easy to do it well, I am constantly working to improve my strategies. Even more important is the role of Messaging in an enterprise context and in the design. I think Message-driven architecture is perhaps the most important to integrate into applications in terms of its scope of applicability and how it lends to scalability. In this vein, Spring Integration becomes a highly intriguing element worthy of study, testing, and integration. I barely touch on Spring Integration here, particulary in its standard usage but simply use a few classes programmatically to decouple JMS implementation from its clients.
Messaging is everywhere and so subtle we are not aware of it, it just happens all around us, all the time. Consider this: in Genetics on a cellular level, which is nongranular in the scope of genetics itself, the major elements in a cell communicate, but how? They are not connected by any physical construct save the mutual environment they are in so how do they do it? They message each other with signals, receptors and a means to translate those messages, which contain instructions.
In Gene expression, DNA/RNA within eukaryote cells (think systems within systems within systems…elements moving in space and time under specific, ever changing constraints and environmental fluctuations (put that in your Agile timebox!) ) communicate by transmitting messages, intercepting, translating and even performing message amplification. There are specialized elements, mRNA specifically, Messenger RNA, which are translated by signal recognition particles… Cool, right? But this happens all around us, outside, in space, everywhere. And it is all decoupled, and therein lies the beauty of messaging.
So what about our applications? Here is one very simple, isolated application of using Spring Integration ( a low-level usage, not very sophisticated ) to decouple your client and server messaging code:
![]() |
So I wrote a little java package that integrates Spring JMS, ActiveMQ, Spring Integration and Flex Messaging for the front end which hooks into either BlazeDS or Livecycle Data Services. I had a bunch of constraints to solve for such as all Destinations had to come from the database, there were lifecycle issues as far as timing of element initializations with the IoC bean creation and Flex Messaging elements being created and having what they needed such as the Flex Messaging adaptors which I resolved by flex java bootstrapping. In another post I will go into the JMS package further. For the topic here let’s focus on the JMS-Spring JMS-Spring Integration bridge.
The image to the left shows the layout of my jms package to facilitate the mapping. In this system, messages come in from 2 areas: the client and java services on the server. Complicated systems will have many more but let’s talk about the 2 that most would have. The client sends messages to the server that are both user messages and operational messages by the system. Java services send messages when certain business rules and criteria are triggered, passing business data and any message-aware object could be sending messages. Sending on the serverTo insure proper usage I created an interface that a service must implement to send to ActiveMQ, called JMSClientSupport. Note all code in this post is simplified. Here, I actually have it returning a validation message if errors occurred so that a business service developer could implement handling per requirements. A Business Entity A Service |
You could have any client sending messages of any nature to the server. In this case I am using Flex. Messages of type <T> are wrapped on the client as an IMessage {AsyncMessage,CommandMessage etc}. When these messages make their way through Blaze or Livecycle, I have it wired to hit this java adapter which is represented in a Hash per FlexDestination for 1:1 FlexDestination : JMS Destination by Flex.
For this example I am implementing the JMS MessageListener to show tight coupling as well as decoupling:
public class FlexMessagingAdapter extends MessagingAdapter implements MessageListener {
// Invoked by Flex when a message comes in from the client to this adapter's Destination
public Object invoke(Message message) {
// a custom interceptor that extracts partition Destination info like ActiveMQ message group or subtopics like STOCKS.NASDAQ for more specific routing
String partition = new DestinationPartitionInterceptor(message).intercept();
jmsService.send(destination, new IntegrationMessageCreator (message, partition));
}
return null;
}
// Decoupled: Invoked when a Message is received from the Spring Integration channel
public void handleMessage(org.springframework.integration.core.Message<?> message) {....}
// Sets the Spring Integration MessageChannel for sending and receiving messages
public void setMessageChannel(MessageChannel messageChannel) {
this.messageChannel = messageChannel;
}
// Tightly coupled with JMS by the MessageListener.onMessage() method
public void onMessage(javax.jms.Message jmsMessage) {
flex.messaging.messages.Message message = new IntegrationMessageCreator(jmsMessage).createMessage(getDestination().getId(), getSubscribers());
if (getMessageService().getMessageBroker().getChannelIds().contains("streaming-amf")) {
MessageBroker broker = MessageBroker.getMessageBroker(null);
broker.routeMessageToService(message, null);
} else {
getMessageService().pushMessageToClients(message, true);
}
}}
I have a second post that show an even more decoupled messaging strategy with Spring Integration but this is purely a a basic idea using Flex Messaging, Spring Integration, Spring JMS and ActiveMQ. I will post the more broad strategy next
Step 1: Client messages are transformed here by extending the JMS MessageCreator. In this class I pull out the data from any Object type but specifically Flex Message and a JMSMessage types.
public class IntegrationMessageCreator implements MessageCreator {
// a few constructors here to handle multiple message types: JMSMessage, Flex Message, Object message, etc
private MessageBuilder createBuilder() {
MessageBuilder builder = null;
if (this.object != null) {
builder = MessageBuilder.withPayload(object);
} else if (this.flexMessage != null && flexMessage.getBody() != null) {
builder = MessageBuilder.withPayload(flexMessage.getBody()).copyHeaders(flexMessage.getHeaders());
}
// ActiveMQ Message Groups
if (this.partition != null) builder.setHeader(MessageConstants.Headers.JMSXGROUPID, partition);
return builder;
}
// to JMS
public javax.jms.Message createMessage(Session session) throws JMSException {
return new IntegrationMessageConverter().toMessage(createBuilder().build(), session);
}
// To Flex
public flex.messaging.messages.Message createMessage(String destinationId, int subscribers) {
Message integrationMessage = (Message) new IntegrationMessageConverter().fromMessage(this.jmsMessage);
flex.messaging.messages.Message flexMessage = new AsyncMessage();
flexMessage.setBody(integrationMessage.getPayload());
flexMessage.setDestination(destinationId);
flexMessage.setHeaders(integrationMessage.getHeaders());
// …and other good jms to flex data
return flexMessage;
}
}
import org.springframework.integration.jms.HeaderMappingMessageConverter;
import org.springframework.integration.core.Message;
import javax.jms.Session;
public class IntegrationMessageConverter extends HeaderMappingMessageConverter {
// Converts from a JMS Message to an Integration Message. You should do a try catch but I cut it out for brevity
public Object fromMessage(javax.jms.Message jmsMessage) throws Exception {
return (Message) super.fromMessage(jmsMessage);
}
// Converts from an Integration Message to a JMS Message. You should do a try catch but I cut it out for brevity
public javax.jms.Message toMessage(Object object, Session session) throws Exception {
return jmsMessage = super.toMessage(object, session);
}
}
In my jmsConfig.xml I configured one Spring MessageListenerAdapter which I have wired with a message delegate, a POJO and its overloaded handleMessage method name:
<bean id=”messageListenerAdapter”>
<property name=”delegate” ref=”defaultMessageDelegate”/>
<property name=”defaultListenerMethod” value=”handleMessage”/>
<property name=”messageConverter” ref=”simpleMessageConverter”/>
</bean>
As the application loads and all Spring beans are initialized, I initialize all of my JMS Destinations. As I do this, I also initialize a MessageListenerAdapter for each Destination. I have a stateless JMSService, which is called by another service, MessagingGateway, to initialize each Destination and which calls PollingListenerContainerFactory to create child MessageListenerAdaptors for each Destination. The adapters are configured based on an abstract parent configuration:
<bean id=”abstractListenerContainer” abstract=”true” destroy-method=”destroy”>
<property name=”connectionFactory” ref=”pooledConnectionFactory”/>
<property name=”transactionManager” ref=”jmsTransActionManager”/>
<property name=”cacheLevel” value=”3″/>
<property name=”taskExecutor” ref=”taskExecutor”/>
<property name=”autoStartup” value=”true”/>
</bean>
Snippet from PollingListenerContainerFactory:
/**
* Gets the parent from the IoC to reduce runtime config and
* resources to create children.
* <p/>
* DefaultMessageListenerContainer is Responsible for all threading
* of message reception and dispatches into the listener for processing.
* Supports dynamic scaling for a higher during peakloads.
*
* @param destination
* @param messageListener
* @return
*/
public static DefaultMessageListenerContainer createMessageListenerContainer(Destination destination, MessageListener messageListener) {
ChildBeanDefinition childBeanDefinition = new ChildBeanDefinition(“abstractListenerContainer”, configureListenerContainer(destination, messageListener));
String beanID = IdGeneratorUtil.getStringId();
ConfigurableListableBeanFactory beanFactory = ApplicationContextAware.getConfigurableListableBeanFactory();
((DefaultListableBeanFactory) beanFactory).registerBeanDefinition(beanID, childBeanDefinition);
DefaultMessageListenerContainer container = (DefaultMessageListenerContainer) ApplicationContextAware.getBean(beanID);
container.setDestination(destination);
return container;
}
/**
* Configures the child listener, based on the parent in jmsConfig.xml.
* <p>Configures Queue or Topic consumers:
* Queue: stick with 1 consumer for low-volume queues: default is
* Topic: there’s no need for more than one concurrent consumer
* Durable Subscription: Only 1 concurrent consumer supported
* <p/>
* props.addPropertyValue(“messageSelector”, “”); sets a message selector for this listener
*
* @param destination
* @param messageListener
* @return
*/
private static MutablePropertyValues configureListenerContainer(Destination destination, MessageListener messageListener) {
MutablePropertyValues props = new MutablePropertyValues();
props.addPropertyValue(“destination”, destination);
props.addPropertyValue(“messageListener”, messageListener);
// Enable throttling on peak loads
if (destination instanceof Queue) {
props.addPropertyValue(“maxConcurrentConsumers”, 50); // modify to needs
}
// Override default setting Point-to-Point (Queues)
if (destination instanceof Topic) {
props.addPropertyValue(“pubSubDomain”, true);
}
return props;
}
this is overkill to this topic but its cool stuff. So we now have a JMS listener for asynchronous JMS reception as well as flex, but now let’s look at the message delegate we wired into the MessageListenerAdapter:
public interface MessageDelegate {
void handleMessage(String message);
void handleMessage(Map message);
void handleMessage(Serializable message);
}
Pretty simple, right? It’s a POJO with absolutely no JMS code whatsoever for asynchronous message reception. How does it work? Spring abstracts the JMS code and calls it behind the scenes, if you look at the source code for Spring’s SimpleMessageConverter, it does the fromMessage() toMessage() handling for you and throws the resultant “message” into the appropriate overloaded method above. Now this is great for simple message abstraction but the above with JMS-Flex and Spring Integration is an example of more complicated handling. With clients you often need to translate and transfer the data from message type 1 to message type 2. In the adapter code above, you would use the handleMessage() method to get the message from Spring Integration and into the message type of your choice, here, a Flex message.
Posted in ActiveMQ, Annotations, Application Cofiguration, Broker Topology, Configuration Management, Flex, JMS, Java, Messaging, Software Development, Spring JMS | No Comments »
Posted by Helena Edelson on 22nd September 2009
Here is one of those interview questions for String modification where you need to solve for an input of 3 letters, and return 3 letters down from each one in the alphabet: My solution isn’t perfect but…after being asked it under interview stress I had to give it a try a few days later
public class Test {
public static void main(String[] args){
List
for(String a : output) {
System.out.println("output:" + a);
}
}
private static List
List
if(s != null && !s.isEmpty()) {
char[] alphabetArray = {'a','b','c','d','e','f','g','h'
,'i','j','k','l','m','n','o','p','q'
,'r','s','t','u','v','w','x','y','z','a','b','c','d','e','f','g','h'
,'i','j','k','l','m','n','o','p','q'
,'r','s','t','u','v','w','x','y','z'};
List
for(char c : alphabetArray) {
alphabet.add(String.valueOf(c));
}
List
for(int i = 0;i < s.length();i++) {
tokens.add(String.valueOf(s.charAt(i)));
}
output = new ArrayList
for(String t : tokens) {
for(int i = 0; i < alphabet.size(); i++) {
if(t.equalsIgnoreCase(alphabet.get(i)) && i <= 26) {
output.add(alphabet.get(i+3));
}}}}
return output;
}
}
Posted in Java | 3 Comments »