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