1
2
3
4
5
6
7
8
9
10
11 package org.mule.construct;
12
13 import org.mule.api.MuleContext;
14 import org.mule.api.MuleEvent;
15 import org.mule.api.MuleException;
16 import org.mule.api.construct.FlowConstructInvalidException;
17 import org.mule.api.construct.Pipeline;
18 import org.mule.api.endpoint.InboundEndpoint;
19 import org.mule.api.processor.MessageProcessor;
20 import org.mule.api.processor.MessageProcessorBuilder;
21 import org.mule.api.processor.MessageProcessorChainBuilder;
22 import org.mule.api.processor.ProcessingStrategy;
23 import org.mule.api.source.CompositeMessageSource;
24 import org.mule.api.source.MessageSource;
25 import org.mule.config.i18n.CoreMessages;
26 import org.mule.construct.flow.DefaultFlowProcessingStrategy;
27 import org.mule.processor.AbstractInterceptingMessageProcessor;
28 import org.mule.processor.chain.DefaultMessageProcessorChainBuilder;
29 import org.mule.processor.strategy.AsynchronousProcessingStrategy;
30 import org.mule.processor.strategy.SynchronousProcessingStrategy;
31
32 import java.util.Collections;
33 import java.util.List;
34
35
36
37
38
39
40
41
42 public abstract class AbstractPipeline extends AbstractFlowConstruct implements Pipeline
43 {
44 protected MessageSource messageSource;
45 protected MessageProcessor pipeline;
46
47 protected List<MessageProcessor> messageProcessors = Collections.emptyList();
48
49 protected ProcessingStrategy processingStrategy;
50
51 public AbstractPipeline(String name, MuleContext muleContext)
52 {
53 super(name, muleContext);
54 processingStrategy = new SynchronousProcessingStrategy();
55 }
56
57
58
59
60
61
62
63
64
65
66
67 protected MessageProcessor createPipeline() throws MuleException
68 {
69 DefaultMessageProcessorChainBuilder builder = new DefaultMessageProcessorChainBuilder(this);
70 builder.setName("'" + getName() + "' processor chain");
71 configurePreProcessors(builder);
72 configureMessageProcessors(builder);
73 configurePostProcessors(builder);
74 return builder.build();
75 }
76
77 protected void configurePreProcessors(MessageProcessorChainBuilder builder) throws MuleException
78 {
79
80 }
81
82 protected void configurePostProcessors(MessageProcessorChainBuilder builder) throws MuleException
83 {
84
85 }
86
87 @Override
88 public void setMessageProcessors(List<MessageProcessor> messageProcessors)
89 {
90 this.messageProcessors = messageProcessors;
91 }
92
93 @Override
94 public List<MessageProcessor> getMessageProcessors()
95 {
96 return messageProcessors;
97 }
98
99 @Override
100 public MessageSource getMessageSource()
101 {
102 return messageSource;
103 }
104
105 @Override
106 public void setMessageSource(MessageSource messageSource)
107 {
108 this.messageSource = messageSource;
109 }
110
111 @Override
112 public ProcessingStrategy getProcessingStrategy()
113 {
114 return processingStrategy;
115 }
116
117 @Override
118 public void setProcessingStrategy(ProcessingStrategy processingStrategy)
119 {
120 this.processingStrategy = processingStrategy;
121 }
122
123 @Override
124 protected void doInitialise() throws MuleException
125 {
126 super.doInitialise();
127
128 pipeline = createPipeline();
129
130 if (messageSource != null)
131 {
132
133 messageSource.setListener(new AbstractInterceptingMessageProcessor()
134 {
135 @Override
136 public MuleEvent process(MuleEvent event) throws MuleException
137 {
138 return pipeline.process(event);
139 }
140 });
141 }
142
143 injectFlowConstructMuleContext(messageSource);
144 injectFlowConstructMuleContext(pipeline);
145 initialiseIfInitialisable(messageSource);
146 initialiseIfInitialisable(pipeline);
147 }
148
149 protected void configureMessageProcessors(MessageProcessorChainBuilder builder) throws MuleException
150 {
151 getProcessingStrategy().configureProcessors(getMessageProcessors(),
152 new ProcessingStrategy.StageNameSource()
153 {
154 @Override
155 public String getName()
156 {
157 return AbstractPipeline.this.getName();
158 }
159 }, builder, muleContext);
160 }
161
162 @Override
163 protected void validateConstruct() throws FlowConstructInvalidException
164 {
165 super.validateConstruct();
166
167
168 boolean userConfiguredAsyncProcessingStrategy = processingStrategy instanceof AsynchronousProcessingStrategy
169 && !(processingStrategy instanceof DefaultFlowProcessingStrategy);
170
171 if (userConfiguredAsyncProcessingStrategy && !isMessageSourceCompatibleWithAsync(messageSource))
172 {
173 throw new FlowConstructInvalidException(
174 CoreMessages.createStaticMessage("One of the inbound endpoint configured on this Flow is not compatible with an asynchronous processing strategy. Either because it is request-response or has a transaction defined."),
175 this);
176 }
177 }
178
179 private boolean isMessageSourceCompatibleWithAsync(MessageSource source)
180 {
181 if (source instanceof InboundEndpoint)
182 {
183 InboundEndpoint endpoint = ((InboundEndpoint) source);
184 return !endpoint.getExchangePattern().hasResponse()
185 && !endpoint.getTransactionConfig().isConfigured();
186 }
187 else if (messageSource instanceof CompositeMessageSource)
188 {
189 for (MessageSource childSource : ((CompositeMessageSource) source).getSources())
190 {
191 if (!isMessageSourceCompatibleWithAsync(childSource))
192 {
193 return false;
194 }
195 }
196 return true;
197 }
198 else
199 {
200 return true;
201 }
202 }
203
204 @Override
205 protected void doStart() throws MuleException
206 {
207 super.doStart();
208 startIfStartable(pipeline);
209 startIfStartable(messageSource);
210 }
211
212 @Override
213 protected void doStop() throws MuleException
214 {
215 stopIfStoppable(messageSource);
216 stopIfStoppable(pipeline);
217 super.doStop();
218 }
219
220 @Override
221 protected void doDispose()
222 {
223 disposeIfDisposable(pipeline);
224 disposeIfDisposable(messageSource);
225 super.doDispose();
226 }
227 }