001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.camel.impl;
018
019 import java.util.ArrayList;
020 import java.util.Collection;
021 import java.util.HashMap;
022 import java.util.List;
023 import java.util.Map;
024 import java.util.concurrent.atomic.AtomicInteger;
025
026 import org.apache.camel.CamelContext;
027 import org.apache.camel.Endpoint;
028 import org.apache.camel.NoSuchEndpointException;
029 import org.apache.camel.Processor;
030 import org.apache.camel.Route;
031 import org.apache.camel.ShutdownRoute;
032 import org.apache.camel.ShutdownRunningTask;
033 import org.apache.camel.management.InstrumentationProcessor;
034 import org.apache.camel.model.FromDefinition;
035 import org.apache.camel.model.ProcessorDefinition;
036 import org.apache.camel.model.RouteDefinition;
037 import org.apache.camel.processor.Pipeline;
038 import org.apache.camel.processor.RoutePolicyProcessor;
039 import org.apache.camel.processor.UnitOfWorkProcessor;
040 import org.apache.camel.spi.InterceptStrategy;
041 import org.apache.camel.spi.RouteContext;
042 import org.apache.camel.spi.RoutePolicy;
043 import org.apache.camel.util.ObjectHelper;
044
045 /**
046 * The context used to activate new routing rules
047 *
048 * @version $Revision: 905995 $
049 */
050 public class DefaultRouteContext implements RouteContext {
051 private final Map<ProcessorDefinition<?>, AtomicInteger> nodeIndex = new HashMap<ProcessorDefinition<?>, AtomicInteger>();
052 private final RouteDefinition route;
053 private FromDefinition from;
054 private final Collection<Route> routes;
055 private Endpoint endpoint;
056 private final List<Processor> eventDrivenProcessors = new ArrayList<Processor>();
057 private CamelContext camelContext;
058 private List<InterceptStrategy> interceptStrategies = new ArrayList<InterceptStrategy>();
059 private InterceptStrategy managedInterceptStrategy;
060 private boolean routeAdded;
061 private Boolean trace;
062 private Boolean stramCache;
063 private Boolean handleFault;
064 private Long delay;
065 private Boolean autoStartup = Boolean.TRUE;
066 private RoutePolicy routePolicy;
067 private ShutdownRoute shutdownRoute;
068 private ShutdownRunningTask shutdownRunningTask;
069
070 public DefaultRouteContext(CamelContext camelContext, RouteDefinition route, FromDefinition from, Collection<Route> routes) {
071 this.camelContext = camelContext;
072 this.route = route;
073 this.from = from;
074 this.routes = routes;
075 }
076
077 /**
078 * Only used for lazy construction from inside ExpressionType
079 */
080 public DefaultRouteContext(CamelContext camelContext) {
081 this.camelContext = camelContext;
082 this.routes = new ArrayList<Route>();
083 this.route = new RouteDefinition("temporary");
084 }
085
086 public Endpoint getEndpoint() {
087 if (endpoint == null) {
088 endpoint = from.resolveEndpoint(this);
089 }
090 return endpoint;
091 }
092
093 public FromDefinition getFrom() {
094 return from;
095 }
096
097 public RouteDefinition getRoute() {
098 return route;
099 }
100
101 public CamelContext getCamelContext() {
102 if (camelContext == null) {
103 camelContext = getRoute().getCamelContext();
104 }
105 return camelContext;
106 }
107
108 public Processor createProcessor(ProcessorDefinition<?> node) throws Exception {
109 return node.createOutputsProcessor(this);
110 }
111
112 public Endpoint resolveEndpoint(String uri) {
113 return route.resolveEndpoint(uri);
114 }
115
116 public Endpoint resolveEndpoint(String uri, String ref) {
117 Endpoint endpoint = null;
118 if (uri != null) {
119 endpoint = resolveEndpoint(uri);
120 if (endpoint == null) {
121 throw new NoSuchEndpointException(uri);
122 }
123 }
124 if (ref != null) {
125 endpoint = lookup(ref, Endpoint.class);
126 if (endpoint == null) {
127 throw new NoSuchEndpointException("ref:" + ref);
128 }
129 }
130 if (endpoint == null) {
131 throw new IllegalArgumentException("Either 'uri' or 'ref' must be specified on: " + this);
132 } else {
133 return endpoint;
134 }
135 }
136
137 public <T> T lookup(String name, Class<T> type) {
138 return getCamelContext().getRegistry().lookup(name, type);
139 }
140
141 public <T> Map<String, T> lookupByType(Class<T> type) {
142 return getCamelContext().getRegistry().lookupByType(type);
143 }
144
145 public void commit() {
146 // now lets turn all of the event driven consumer processors into a single route
147 if (!eventDrivenProcessors.isEmpty()) {
148 Processor processor = Pipeline.newInstance(eventDrivenProcessors);
149
150 // and wrap it in a unit of work so the UoW is on the top, so the entire route will be in the same UoW
151 Processor unitOfWorkProcessor = new UnitOfWorkProcessor(this, processor);
152 Processor target = unitOfWorkProcessor;
153
154 // and then optionally add route policy processor if a custom policy is set
155 RoutePolicyProcessor routePolicyProcessor = null;
156 RoutePolicy policy = getRoutePolicy();
157 if (policy != null) {
158 routePolicyProcessor = new RoutePolicyProcessor(unitOfWorkProcessor, policy);
159 // add it as service if we have not already done that (eg possible if two routes have the same service)
160 if (!camelContext.hasService(policy)) {
161 try {
162 camelContext.addService(policy);
163 } catch (Exception e) {
164 throw ObjectHelper.wrapRuntimeCamelException(e);
165 }
166 }
167 target = routePolicyProcessor;
168 }
169
170 // and wrap it by a instrumentation processor that is to be used for performance stats
171 // for this particular route
172 InstrumentationProcessor wrapper = new InstrumentationProcessor();
173 wrapper.setType("route");
174 wrapper.setProcessor(target);
175
176 // and create the route that wraps the UoW
177 Route edcr = new EventDrivenConsumerRoute(this, getEndpoint(), wrapper);
178 edcr.getProperties().put(Route.ID_PROPERTY, route.idOrCreate(getCamelContext().getNodeIdFactory()));
179 edcr.getProperties().put(Route.PARENT_PROPERTY, Integer.toHexString(route.hashCode()));
180 if (route.getGroup() != null) {
181 edcr.getProperties().put(Route.GROUP_PROPERTY, route.getGroup());
182 }
183
184 // after the route is created then set the route on the policy processor so we get hold of it
185 if (routePolicyProcessor != null) {
186 routePolicyProcessor.setRoute(edcr);
187 }
188
189 routes.add(edcr);
190 }
191 }
192
193 public void addEventDrivenProcessor(Processor processor) {
194 eventDrivenProcessors.add(processor);
195 }
196
197 public List<InterceptStrategy> getInterceptStrategies() {
198 return interceptStrategies;
199 }
200
201 public void setInterceptStrategies(List<InterceptStrategy> interceptStrategies) {
202 this.interceptStrategies = interceptStrategies;
203 }
204
205 public void addInterceptStrategy(InterceptStrategy interceptStrategy) {
206 getInterceptStrategies().add(interceptStrategy);
207 }
208
209 public void setManagedInterceptStrategy(InterceptStrategy interceptStrategy) {
210 this.managedInterceptStrategy = interceptStrategy;
211 }
212
213 public InterceptStrategy getManagedInterceptStrategy() {
214 return managedInterceptStrategy;
215 }
216
217 public boolean isRouteAdded() {
218 return routeAdded;
219 }
220
221 public void setIsRouteAdded(boolean routeAdded) {
222 this.routeAdded = routeAdded;
223 }
224
225 public void setTracing(Boolean tracing) {
226 this.trace = tracing;
227 }
228
229 public Boolean isTracing() {
230 if (trace != null) {
231 return trace;
232 } else {
233 // fallback to the option from camel context
234 return getCamelContext().isTracing();
235 }
236 }
237
238 public void setStreamCaching(Boolean cache) {
239 this.stramCache = cache;
240 }
241
242 public Boolean isStreamCaching() {
243 if (stramCache != null) {
244 return stramCache;
245 } else {
246 // fallback to the option from camel context
247 return getCamelContext().isStreamCaching();
248 }
249 }
250
251 public void setHandleFault(Boolean handleFault) {
252 this.handleFault = handleFault;
253 }
254
255 public Boolean isHandleFault() {
256 if (handleFault != null) {
257 return handleFault;
258 } else {
259 // fallback to the option from camel context
260 return getCamelContext().isHandleFault();
261 }
262 }
263
264 public void setDelayer(Long delay) {
265 this.delay = delay;
266 }
267
268 public Long getDelayer() {
269 if (delay != null) {
270 return delay;
271 } else {
272 // fallback to the option from camel context
273 return getCamelContext().getDelayer();
274 }
275 }
276
277 public void setAutoStartup(Boolean autoStartup) {
278 this.autoStartup = autoStartup;
279 }
280
281 public Boolean isAutoStartup() {
282 if (autoStartup != null) {
283 return autoStartup;
284 }
285 // default to true
286 return true;
287 }
288
289 public void setShutdownRoute(ShutdownRoute shutdownRoute) {
290 this.shutdownRoute = shutdownRoute;
291 }
292
293 public ShutdownRoute getShutdownRoute() {
294 if (shutdownRoute != null) {
295 return shutdownRoute;
296 } else {
297 // fallback to the option from camel context
298 return getCamelContext().getShutdownRoute();
299 }
300 }
301
302 public void setShutdownRunningTask(ShutdownRunningTask shutdownRunningTask) {
303 this.shutdownRunningTask = shutdownRunningTask;
304 }
305
306 public ShutdownRunningTask getShutdownRunningTask() {
307 if (shutdownRunningTask != null) {
308 return shutdownRunningTask;
309 } else {
310 // fallback to the option from camel context
311 return getCamelContext().getShutdownRunningTask();
312 }
313 }
314
315 public RoutePolicy getRoutePolicy() {
316 return routePolicy;
317 }
318
319 public void setRoutePolicy(RoutePolicy routePolicy) {
320 this.routePolicy = routePolicy;
321 }
322
323 public int getAndIncrement(ProcessorDefinition<?> node) {
324 AtomicInteger count = nodeIndex.get(node);
325 if (count == null) {
326 count = new AtomicInteger();
327 nodeIndex.put(node, count);
328 }
329 return count.getAndIncrement();
330 }
331 }