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 */ 017package org.apache.camel.impl; 018 019import java.util.Collection; 020import java.util.List; 021import java.util.Map; 022import java.util.concurrent.ExecutorService; 023import java.util.function.Function; 024 025import org.apache.camel.AsyncProcessor; 026import org.apache.camel.CatalogCamelContext; 027import org.apache.camel.Processor; 028import org.apache.camel.health.HealthCheckRegistry; 029import org.apache.camel.impl.engine.AbstractCamelContext; 030import org.apache.camel.impl.engine.BaseRouteService; 031import org.apache.camel.impl.engine.DefaultTransformerRegistry; 032import org.apache.camel.impl.engine.DefaultValidatorRegistry; 033import org.apache.camel.impl.transformer.TransformerKey; 034import org.apache.camel.impl.validator.ValidatorKey; 035import org.apache.camel.model.DataFormatDefinition; 036import org.apache.camel.model.HystrixConfigurationDefinition; 037import org.apache.camel.model.Model; 038import org.apache.camel.model.ModelCamelContext; 039import org.apache.camel.model.ProcessorDefinition; 040import org.apache.camel.model.Resilience4jConfigurationDefinition; 041import org.apache.camel.model.RouteDefinition; 042import org.apache.camel.model.cloud.ServiceCallConfigurationDefinition; 043import org.apache.camel.model.rest.RestDefinition; 044import org.apache.camel.model.transformer.TransformerDefinition; 045import org.apache.camel.model.validator.ValidatorDefinition; 046import org.apache.camel.processor.MulticastProcessor; 047import org.apache.camel.reifier.dataformat.DataFormatReifier; 048import org.apache.camel.spi.DataFormat; 049import org.apache.camel.spi.Registry; 050import org.apache.camel.spi.TransformerRegistry; 051import org.apache.camel.spi.ValidatorRegistry; 052import org.apache.camel.support.CamelContextHelper; 053import org.slf4j.Logger; 054import org.slf4j.LoggerFactory; 055 056/** 057 * Represents the context used to configure routes and the policies to use. 058 */ 059public abstract class AbstractModelCamelContext extends AbstractCamelContext implements ModelCamelContext, CatalogCamelContext { 060 061 private static final Logger LOG = LoggerFactory.getLogger(AbstractModelCamelContext.class); 062 063 private final Model model = new DefaultModel(this); 064 065 /** 066 * Creates the {@link ModelCamelContext} using 067 * {@link org.apache.camel.support.DefaultRegistry} as registry. 068 * <p/> 069 * Use one of the other constructors to force use an explicit registry. 070 */ 071 public AbstractModelCamelContext() { 072 this(true); 073 } 074 075 /** 076 * Creates the {@link ModelCamelContext} using the given registry 077 * 078 * @param registry the registry 079 */ 080 public AbstractModelCamelContext(Registry registry) { 081 this(); 082 setRegistry(registry); 083 } 084 085 public AbstractModelCamelContext(boolean init) { 086 super(false); 087 088 setDefaultExtension(HealthCheckRegistry.class, this::createHealthCheckRegistry); 089 090 if (init) { 091 init(); 092 } 093 } 094 095 @Override 096 public List<RouteDefinition> getRouteDefinitions() { 097 return model.getRouteDefinitions(); 098 } 099 100 @Override 101 public RouteDefinition getRouteDefinition(String id) { 102 return model.getRouteDefinition(id); 103 } 104 105 @Override 106 public void addRouteDefinitions(Collection<RouteDefinition> routeDefinitions) throws Exception { 107 if (isStarted() && !isAllowAddingNewRoutes()) { 108 throw new IllegalArgumentException("Adding new routes after CamelContext has been started is not allowed"); 109 } 110 model.addRouteDefinitions(routeDefinitions); 111 } 112 113 @Override 114 public void addRouteDefinition(RouteDefinition routeDefinition) throws Exception { 115 if (isStarted() && !isAllowAddingNewRoutes()) { 116 throw new IllegalArgumentException("Adding new routes after CamelContext has been started is not allowed"); 117 } 118 model.addRouteDefinition(routeDefinition); 119 } 120 121 @Override 122 public void removeRouteDefinitions(Collection<RouteDefinition> routeDefinitions) throws Exception { 123 model.removeRouteDefinitions(routeDefinitions); 124 } 125 126 @Override 127 public void removeRouteDefinition(RouteDefinition routeDefinition) throws Exception { 128 model.removeRouteDefinition(routeDefinition); 129 } 130 131 @Override 132 public List<RestDefinition> getRestDefinitions() { 133 return model.getRestDefinitions(); 134 } 135 136 @Override 137 public void addRestDefinitions(Collection<RestDefinition> restDefinitions, boolean addToRoutes) throws Exception { 138 if (isStarted() && !isAllowAddingNewRoutes()) { 139 throw new IllegalArgumentException("Adding new routes after CamelContext has been started is not allowed"); 140 } 141 model.addRestDefinitions(restDefinitions, addToRoutes); 142 } 143 144 @Override 145 public void setDataFormats(Map<String, DataFormatDefinition> dataFormats) { 146 model.setDataFormats(dataFormats); 147 } 148 149 @Override 150 public Map<String, DataFormatDefinition> getDataFormats() { 151 return model.getDataFormats(); 152 } 153 154 @Override 155 public DataFormatDefinition resolveDataFormatDefinition(String name) { 156 return model.resolveDataFormatDefinition(name); 157 } 158 159 @Override 160 public ProcessorDefinition getProcessorDefinition(String id) { 161 return model.getProcessorDefinition(id); 162 } 163 164 @Override 165 public <T extends ProcessorDefinition> T getProcessorDefinition(String id, Class<T> type) { 166 return model.getProcessorDefinition(id, type); 167 } 168 169 @Override 170 public void setValidators(List<ValidatorDefinition> validators) { 171 model.setValidators(validators); 172 } 173 174 @Override 175 public HystrixConfigurationDefinition getHystrixConfiguration(String id) { 176 return model.getHystrixConfiguration(id); 177 } 178 179 @Override 180 public void setHystrixConfiguration(HystrixConfigurationDefinition configuration) { 181 model.setHystrixConfiguration(configuration); 182 } 183 184 @Override 185 public void setHystrixConfigurations(List<HystrixConfigurationDefinition> configurations) { 186 model.setHystrixConfigurations(configurations); 187 } 188 189 @Override 190 public void addHystrixConfiguration(String id, HystrixConfigurationDefinition configuration) { 191 model.addHystrixConfiguration(id, configuration); 192 } 193 194 @Override 195 public Resilience4jConfigurationDefinition getResilience4jConfiguration(String id) { 196 return model.getResilience4jConfiguration(id); 197 } 198 199 @Override 200 public void setResilience4jConfiguration(Resilience4jConfigurationDefinition configuration) { 201 model.setResilience4jConfiguration(configuration); 202 } 203 204 @Override 205 public void setResilience4jConfigurations(List<Resilience4jConfigurationDefinition> configurations) { 206 model.setResilience4jConfigurations(configurations); 207 } 208 209 @Override 210 public void addResilience4jConfiguration(String id, Resilience4jConfigurationDefinition configuration) { 211 model.addResilience4jConfiguration(id, configuration); 212 } 213 214 @Override 215 public List<ValidatorDefinition> getValidators() { 216 return model.getValidators(); 217 } 218 219 @Override 220 public void setTransformers(List<TransformerDefinition> transformers) { 221 model.setTransformers(transformers); 222 } 223 224 @Override 225 public List<TransformerDefinition> getTransformers() { 226 return model.getTransformers(); 227 } 228 229 @Override 230 public ServiceCallConfigurationDefinition getServiceCallConfiguration(String serviceName) { 231 return model.getServiceCallConfiguration(serviceName); 232 } 233 234 @Override 235 public void setServiceCallConfiguration(ServiceCallConfigurationDefinition configuration) { 236 model.setServiceCallConfiguration(configuration); 237 } 238 239 @Override 240 public void setServiceCallConfigurations(List<ServiceCallConfigurationDefinition> configurations) { 241 model.setServiceCallConfigurations(configurations); 242 } 243 244 @Override 245 public void addServiceCallConfiguration(String serviceName, ServiceCallConfigurationDefinition configuration) { 246 model.addServiceCallConfiguration(serviceName, configuration); 247 } 248 249 @Override 250 public void setRouteFilterPattern(String include, String exclude) { 251 model.setRouteFilterPattern(include, exclude); 252 } 253 254 @Override 255 public void setRouteFilter(Function<RouteDefinition, Boolean> filter) { 256 model.setRouteFilter(filter); 257 } 258 259 @Override 260 public Function<RouteDefinition, Boolean> getRouteFilter() { 261 return model.getRouteFilter(); 262 } 263 264 @Override 265 protected ValidatorRegistry<ValidatorKey> createValidatorRegistry() { 266 return new DefaultValidatorRegistry(this); 267 } 268 269 @Override 270 protected TransformerRegistry<TransformerKey> createTransformerRegistry() { 271 return new DefaultTransformerRegistry(this); 272 } 273 274 protected abstract HealthCheckRegistry createHealthCheckRegistry(); 275 276 @Override 277 protected void doStartStandardServices() { 278 super.doStartStandardServices(); 279 } 280 281 @Override 282 protected void doStartEagerServices() { 283 getExtension(HealthCheckRegistry.class); 284 super.doStartEagerServices(); 285 } 286 287 @Override 288 protected void bindDataFormats() throws Exception { 289 // eager lookup data formats and bind to registry so the dataformats can 290 // be looked up and used 291 for (Map.Entry<String, DataFormatDefinition> e : model.getDataFormats().entrySet()) { 292 String id = e.getKey(); 293 DataFormatDefinition def = e.getValue(); 294 LOG.debug("Creating Dataformat with id: {} and definition: {}", id, def); 295 DataFormat df = DataFormatReifier.reifier(this, def).createDataFormat(); 296 addService(df, true); 297 getRegistry().bind(id, df); 298 } 299 } 300 301 @Override 302 protected synchronized void shutdownRouteService(BaseRouteService routeService) throws Exception { 303 if (routeService instanceof RouteService) { 304 model.getRouteDefinitions().remove(((RouteService)routeService).getRouteDefinition()); 305 } 306 super.shutdownRouteService(routeService); 307 } 308 309 @Override 310 protected boolean isStreamCachingInUse() throws Exception { 311 boolean streamCachingInUse = super.isStreamCachingInUse(); 312 if (!streamCachingInUse) { 313 for (RouteDefinition route : model.getRouteDefinitions()) { 314 Boolean routeCache = CamelContextHelper.parseBoolean(this, route.getStreamCache()); 315 if (routeCache != null && routeCache) { 316 streamCachingInUse = true; 317 break; 318 } 319 } 320 } 321 return streamCachingInUse; 322 } 323 324 @Override 325 public void startRouteDefinitions() throws Exception { 326 model.startRouteDefinitions(); 327 } 328 329 @Override 330 public AsyncProcessor createMulticast(Collection<Processor> processors, ExecutorService executor, boolean shutdownExecutorService) { 331 return new MulticastProcessor(this, processors, null, true, executor, shutdownExecutorService, false, false, 0, null, false, false); 332 } 333 334}