All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.camel.builder.RouteBuilder Maven / Gradle / Ivy

There is a newer version: 4.6.0
Show newest version
/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.camel.builder;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;

import org.apache.camel.CamelContext;
import org.apache.camel.Component;
import org.apache.camel.Endpoint;
import org.apache.camel.RoutesBuilder;
import org.apache.camel.component.properties.PropertiesComponent;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.model.FromDefinition;
import org.apache.camel.model.InterceptDefinition;
import org.apache.camel.model.InterceptFromDefinition;
import org.apache.camel.model.InterceptSendToEndpointDefinition;
import org.apache.camel.model.ModelCamelContext;
import org.apache.camel.model.OnCompletionDefinition;
import org.apache.camel.model.OnExceptionDefinition;
import org.apache.camel.model.RouteDefinition;
import org.apache.camel.model.RoutesDefinition;
import org.apache.camel.model.rest.RestConfigurationDefinition;
import org.apache.camel.model.rest.RestDefinition;
import org.apache.camel.model.rest.RestsDefinition;
import org.apache.camel.spi.RestConfiguration;
import org.apache.camel.util.ObjectHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A Java DSL which is
 * used to build {@link org.apache.camel.impl.DefaultRoute} instances in a {@link CamelContext} for smart routing.
 *
 * @version 
 */
public abstract class RouteBuilder extends BuilderSupport implements RoutesBuilder {
    protected Logger log = LoggerFactory.getLogger(getClass());
    private AtomicBoolean initialized = new AtomicBoolean(false);
    private RestsDefinition restCollection = new RestsDefinition();
    private Map restConfigurations;
    private List transformerBuilders = new ArrayList<>();
    private List validatorBuilders = new ArrayList<>();
    private RoutesDefinition routeCollection = new RoutesDefinition();

    public RouteBuilder() {
        this(null);
    }

    public RouteBuilder(CamelContext context) {
        super(context);
    }

    @Override
    public String toString() {
        return getRouteCollection().toString();
    }

    /**
     * Called on initialization to build the routes using the fluent builder syntax.
     * 

* This is a central method for RouteBuilder implementations to implement * the routes using the Java fluent builder syntax. * * @throws Exception can be thrown during configuration */ public abstract void configure() throws Exception; /** * Configures the REST services * * @return the builder */ public RestConfigurationDefinition restConfiguration() { return restConfiguration(""); } /** * Configures the REST service for the given component * * @return the builder */ public RestConfigurationDefinition restConfiguration(String component) { if (restConfigurations == null) { restConfigurations = new HashMap(); } RestConfigurationDefinition restConfiguration = restConfigurations.get(component); if (restConfiguration == null) { restConfiguration = new RestConfigurationDefinition(); if (!component.isEmpty()) { restConfiguration.component(component); } restConfigurations.put(component, restConfiguration); } return restConfiguration; } /** * Creates a new REST service * * @return the builder */ public RestDefinition rest() { getRestCollection().setCamelContext(getContext()); RestDefinition answer = getRestCollection().rest(); configureRest(answer); return answer; } /** * Creates a new REST service * * @param path the base path * @return the builder */ public RestDefinition rest(String path) { getRestCollection().setCamelContext(getContext()); RestDefinition answer = getRestCollection().rest(path); configureRest(answer); return answer; } /** * Create a new {@code TransformerBuilder}. * * @return the builder */ public TransformerBuilder transformer() { TransformerBuilder tdb = new TransformerBuilder(); transformerBuilders.add(tdb); return tdb; } /** * Create a new {@code ValidatorBuilder}. * * @return the builder */ public ValidatorBuilder validator() { ValidatorBuilder vb = new ValidatorBuilder(); validatorBuilders.add(vb); return vb; } /** * Creates a new route from the given URI input * * @param uri the from uri * @return the builder */ public RouteDefinition from(String uri) { getRouteCollection().setCamelContext(getContext()); RouteDefinition answer = getRouteCollection().from(uri); configureRoute(answer); return answer; } /** * Creates a new route from the given URI input * * @param uri the String formatted from uri * @param args arguments for the string formatting of the uri * @return the builder */ public RouteDefinition fromF(String uri, Object... args) { getRouteCollection().setCamelContext(getContext()); RouteDefinition answer = getRouteCollection().from(String.format(uri, args)); configureRoute(answer); return answer; } /** * Creates a new route from the given endpoint * * @param endpoint the from endpoint * @return the builder */ public RouteDefinition from(Endpoint endpoint) { getRouteCollection().setCamelContext(getContext()); RouteDefinition answer = getRouteCollection().from(endpoint); configureRoute(answer); return answer; } /** * Creates a new route from the given URIs input * * @param uris the from uris * @return the builder */ public RouteDefinition from(String... uris) { getRouteCollection().setCamelContext(getContext()); RouteDefinition answer = getRouteCollection().from(uris); configureRoute(answer); return answer; } /** * Creates a new route from the given endpoint * * @param endpoints the from endpoints * @return the builder */ public RouteDefinition from(Endpoint... endpoints) { getRouteCollection().setCamelContext(getContext()); RouteDefinition answer = getRouteCollection().from(endpoints); configureRoute(answer); return answer; } /** * Installs the given error handler builder * * @param errorHandlerBuilder the error handler to be used by default for all child routes */ public void errorHandler(ErrorHandlerBuilder errorHandlerBuilder) { if (!getRouteCollection().getRoutes().isEmpty()) { throw new IllegalArgumentException("errorHandler must be defined before any routes in the RouteBuilder"); } getRouteCollection().setCamelContext(getContext()); setErrorHandlerBuilder(errorHandlerBuilder); } /** * Injects a property placeholder value with the given key converted to the given type. * * @param key the property key * @param type the type to convert the value as * @return the value, or null if value is empty * @throws Exception is thrown if property with key not found or error converting to the given type. */ public T propertyInject(String key, Class type) throws Exception { ObjectHelper.notEmpty(key, "key"); ObjectHelper.notNull(type, "Class type"); // the properties component is mandatory Component component = getContext().hasComponent("properties"); if (component == null) { throw new IllegalArgumentException("PropertiesComponent with name properties must be defined" + " in CamelContext to support property placeholders in expressions"); } PropertiesComponent pc = getContext().getTypeConverter() .mandatoryConvertTo(PropertiesComponent.class, component); // enclose key with {{ }} to force parsing Object value = pc.parseUri(pc.getPrefixToken() + key + pc.getSuffixToken()); if (value != null) { return getContext().getTypeConverter().mandatoryConvertTo(type, value); } else { return null; } } /** * Adds a route for an interceptor that intercepts every processing step. * * @return the builder */ public InterceptDefinition intercept() { if (!getRouteCollection().getRoutes().isEmpty()) { throw new IllegalArgumentException("intercept must be defined before any routes in the RouteBuilder"); } getRouteCollection().setCamelContext(getContext()); return getRouteCollection().intercept(); } /** * Adds a route for an interceptor that intercepts incoming messages on any inputs in this route * * @return the builder */ public InterceptFromDefinition interceptFrom() { if (!getRouteCollection().getRoutes().isEmpty()) { throw new IllegalArgumentException("interceptFrom must be defined before any routes in the RouteBuilder"); } getRouteCollection().setCamelContext(getContext()); return getRouteCollection().interceptFrom(); } /** * Adds a route for an interceptor that intercepts incoming messages on the given endpoint. * * @param uri endpoint uri * @return the builder */ public InterceptFromDefinition interceptFrom(String uri) { if (!getRouteCollection().getRoutes().isEmpty()) { throw new IllegalArgumentException("interceptFrom must be defined before any routes in the RouteBuilder"); } getRouteCollection().setCamelContext(getContext()); return getRouteCollection().interceptFrom(uri); } /** * Applies a route for an interceptor if an exchange is send to the given endpoint * * @param uri endpoint uri * @return the builder */ public InterceptSendToEndpointDefinition interceptSendToEndpoint(String uri) { if (!getRouteCollection().getRoutes().isEmpty()) { throw new IllegalArgumentException("interceptSendToEndpoint must be defined before any routes in the RouteBuilder"); } getRouteCollection().setCamelContext(getContext()); return getRouteCollection().interceptSendToEndpoint(uri); } /** * Exception clause * for catching certain exceptions and handling them. * * @param exception exception to catch * @return the builder */ public OnExceptionDefinition onException(Class exception) { // is only allowed at the top currently if (!getRouteCollection().getRoutes().isEmpty()) { throw new IllegalArgumentException("onException must be defined before any routes in the RouteBuilder"); } getRouteCollection().setCamelContext(getContext()); return getRouteCollection().onException(exception); } /** * Exception clause * for catching certain exceptions and handling them. * * @param exceptions list of exceptions to catch * @return the builder */ public OnExceptionDefinition onException(Class... exceptions) { OnExceptionDefinition last = null; for (Class ex : exceptions) { last = last == null ? onException(ex) : last.onException(ex); } return last != null ? last : onException(Exception.class); } /** * On completion * callback for doing custom routing when the {@link org.apache.camel.Exchange} is complete. * * @return the builder */ public OnCompletionDefinition onCompletion() { // is only allowed at the top currently if (!getRouteCollection().getRoutes().isEmpty()) { throw new IllegalArgumentException("onCompletion must be defined before any routes in the RouteBuilder"); } getRouteCollection().setCamelContext(getContext()); return getRouteCollection().onCompletion(); } // Properties // ----------------------------------------------------------------------- public ModelCamelContext getContext() { ModelCamelContext context = super.getContext(); if (context == null) { context = createContainer(); setContext(context); } return context; } public void addRoutesToCamelContext(CamelContext context) throws Exception { // must configure routes before rests configureRoutes((ModelCamelContext) context); configureRests((ModelCamelContext) context); // but populate rests before routes, as we want to turn rests into routes populateRests(); populateTransformers(); populateValidators(); populateRoutes(); } /** * Configures the routes * * @param context the Camel context * @return the routes configured * @throws Exception can be thrown during configuration */ public RoutesDefinition configureRoutes(ModelCamelContext context) throws Exception { setContext(context); checkInitialized(); routeCollection.setCamelContext(context); return routeCollection; } /** * Configures the rests * * @param context the Camel context * @return the rests configured * @throws Exception can be thrown during configuration */ public RestsDefinition configureRests(ModelCamelContext context) throws Exception { setContext(context); restCollection.setCamelContext(context); return restCollection; } /** * Includes the routes from the build to this builder. *

* This allows you to use other builds as route templates. * @param routes other builder with routes to include * * @throws Exception can be thrown during configuration */ public void includeRoutes(RoutesBuilder routes) throws Exception { // TODO: We should support including multiple routes so I think invoking configure() // needs to be deferred to later if (routes instanceof RouteBuilder) { // if its a RouteBuilder then let it use my route collection and error handler // then we are integrated seamless RouteBuilder builder = (RouteBuilder) routes; builder.setContext(this.getContext()); builder.setRouteCollection(this.getRouteCollection()); builder.setRestCollection(this.getRestCollection()); builder.setErrorHandlerBuilder(this.getErrorHandlerBuilder()); // must invoke configure on the original builder so it adds its configuration to me builder.configure(); } else { getContext().addRoutes(routes); } } @Override public void setErrorHandlerBuilder(ErrorHandlerBuilder errorHandlerBuilder) { super.setErrorHandlerBuilder(errorHandlerBuilder); getRouteCollection().setErrorHandlerBuilder(getErrorHandlerBuilder()); } // Implementation methods // ----------------------------------------------------------------------- @SuppressWarnings("deprecation") protected void checkInitialized() throws Exception { if (initialized.compareAndSet(false, true)) { // Set the CamelContext ErrorHandler here ModelCamelContext camelContext = getContext(); if (camelContext.getErrorHandlerBuilder() != null) { setErrorHandlerBuilder(camelContext.getErrorHandlerBuilder()); } configure(); // mark all route definitions as custom prepared because // a route builder prepares the route definitions correctly already for (RouteDefinition route : getRouteCollection().getRoutes()) { route.markPrepared(); } } } protected void populateRoutes() throws Exception { ModelCamelContext camelContext = getContext(); if (camelContext == null) { throw new IllegalArgumentException("CamelContext has not been injected!"); } getRouteCollection().setCamelContext(camelContext); camelContext.addRouteDefinitions(getRouteCollection().getRoutes()); } protected void populateRests() throws Exception { ModelCamelContext camelContext = getContext(); if (camelContext == null) { throw new IllegalArgumentException("CamelContext has not been injected!"); } getRestCollection().setCamelContext(camelContext); // setup rest configuration before adding the rests if (getRestConfigurations() != null) { for (Map.Entry entry : getRestConfigurations().entrySet()) { RestConfiguration config = entry.getValue().asRestConfiguration(getContext()); if ("".equals(entry.getKey())) { camelContext.setRestConfiguration(config); } else { camelContext.addRestConfiguration(config); } } } camelContext.addRestDefinitions(getRestCollection().getRests()); // convert rests into routes so we they are routes for runtime List routes = new ArrayList(); for (RestDefinition rest : getRestCollection().getRests()) { List list = rest.asRouteDefinition(getContext()); routes.addAll(list); } // convert rests api-doc into routes so they are routes for runtime for (RestConfiguration config : camelContext.getRestConfigurations()) { if (config.getApiContextPath() != null) { // avoid adding rest-api multiple times, in case multiple RouteBuilder classes is added // to the CamelContext, as we only want to setup rest-api once // so we check all existing routes if they have rest-api route already added boolean hasRestApi = false; for (RouteDefinition route : camelContext.getRouteDefinitions()) { FromDefinition from = route.getInputs().get(0); if (from.getUri() != null && from.getUri().startsWith("rest-api:")) { hasRestApi = true; } } if (!hasRestApi) { RouteDefinition route = RestDefinition.asRouteApiDefinition(camelContext, config); log.debug("Adding routeId: {} as rest-api route", route.getId()); routes.add(route); } } } // add the rest routes for (RouteDefinition route : routes) { getRouteCollection().route(route); } } protected void populateTransformers() { ModelCamelContext camelContext = getContext(); if (camelContext == null) { throw new IllegalArgumentException("CamelContext has not been injected!"); } for (TransformerBuilder tdb : transformerBuilders) { tdb.configure(camelContext); } } protected void populateValidators() { ModelCamelContext camelContext = getContext(); if (camelContext == null) { throw new IllegalArgumentException("CamelContext has not been injected!"); } for (ValidatorBuilder vb : validatorBuilders) { vb.configure(camelContext); } } public RestsDefinition getRestCollection() { return restCollection; } public Map getRestConfigurations() { return restConfigurations; } public void setRestCollection(RestsDefinition restCollection) { this.restCollection = restCollection; } public void setRouteCollection(RoutesDefinition routeCollection) { this.routeCollection = routeCollection; } public RoutesDefinition getRouteCollection() { return this.routeCollection; } /** * Factory method * * @return the CamelContext */ protected ModelCamelContext createContainer() { return new DefaultCamelContext(); } protected void configureRest(RestDefinition rest) { // noop } protected void configureRoute(RouteDefinition route) { // noop } /** * Adds a collection of routes to this context * * @param routes the routes * @throws Exception if the routes could not be created for whatever reason * @deprecated will be removed in Camel 3.0. Instead use {@link #includeRoutes(org.apache.camel.RoutesBuilder) includeRoutes} instead. */ @Deprecated protected void addRoutes(RoutesBuilder routes) throws Exception { includeRoutes(routes); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy