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.builder; 018 019import java.util.ArrayList; 020import java.util.List; 021 022import org.apache.camel.Endpoint; 023import org.apache.camel.impl.InterceptSendToMockEndpointStrategy; 024import org.apache.camel.model.ProcessorDefinition; 025import org.apache.camel.model.RouteDefinition; 026import org.apache.camel.util.ObjectHelper; 027 028/** 029 * A {@link RouteBuilder} which has extended capabilities when using 030 * the <a href="http://camel.apache.org/advicewith.html">advice with</a> feature. 031 * <p/> 032 * <b>Important:</b> It is recommended to only advice a given route once (you can of course advice multiple routes). 033 * If you do it multiple times, then it may not work as expected, especially when any kind of error handling is involved. 034 * The Camel team plan for Camel 3.0 to support this as internal refactorings in the routing engine is needed to support this properly. 035 * 036 * @see org.apache.camel.model.RouteDefinition#adviceWith(org.apache.camel.CamelContext, RouteBuilder) 037 */ 038public abstract class AdviceWithRouteBuilder extends RouteBuilder { 039 040 private RouteDefinition originalRoute; 041 private final List<AdviceWithTask> adviceWithTasks = new ArrayList<AdviceWithTask>(); 042 043 /** 044 * Sets the original route which we advice. 045 * 046 * @param originalRoute the original route we advice. 047 */ 048 public void setOriginalRoute(RouteDefinition originalRoute) { 049 this.originalRoute = originalRoute; 050 } 051 052 /** 053 * Gets the original route we advice. 054 * 055 * @return the original route. 056 */ 057 public RouteDefinition getOriginalRoute() { 058 return originalRoute; 059 } 060 061 /** 062 * Gets a list of additional tasks to execute after the {@link #configure()} method has been executed 063 * during the advice process. 064 * 065 * @return a list of additional {@link AdviceWithTask} tasks to be executed during the advice process. 066 */ 067 public List<AdviceWithTask> getAdviceWithTasks() { 068 return adviceWithTasks; 069 } 070 071 /** 072 * Mock all endpoints in the route. 073 * 074 * @throws Exception can be thrown if error occurred 075 */ 076 public void mockEndpoints() throws Exception { 077 getContext().addRegisterEndpointCallback(new InterceptSendToMockEndpointStrategy(null)); 078 } 079 080 /** 081 * Mock all endpoints matching the given pattern. 082 * 083 * @param pattern the pattern(s). 084 * @throws Exception can be thrown if error occurred 085 * @see org.apache.camel.util.EndpointHelper#matchEndpoint(org.apache.camel.CamelContext, String, String) 086 */ 087 public void mockEndpoints(String... pattern) throws Exception { 088 for (String s : pattern) { 089 getContext().addRegisterEndpointCallback(new InterceptSendToMockEndpointStrategy(s)); 090 } 091 } 092 093 /** 094 * Mock all endpoints matching the given pattern, and <b>skips</b> sending to the original endpoint (detour messages). 095 * 096 * @param pattern the pattern(s). 097 * @throws Exception can be thrown if error occurred 098 * @see org.apache.camel.util.EndpointHelper#matchEndpoint(org.apache.camel.CamelContext, String, String) 099 */ 100 public void mockEndpointsAndSkip(String... pattern) throws Exception { 101 for (String s : pattern) { 102 getContext().addRegisterEndpointCallback(new InterceptSendToMockEndpointStrategy(s, true)); 103 } 104 } 105 106 /** 107 * Replaces the route from endpoint with a new uri 108 * 109 * @param uri uri of the new endpoint 110 */ 111 public void replaceFromWith(String uri) { 112 ObjectHelper.notNull(originalRoute, "originalRoute", this); 113 getAdviceWithTasks().add(AdviceWithTasks.replaceFromWith(originalRoute, uri)); 114 } 115 116 /** 117 * Replaces the route from endpoint with a new endpoint 118 * 119 * @param endpoint the new endpoint 120 */ 121 public void replaceFromWith(Endpoint endpoint) { 122 ObjectHelper.notNull(originalRoute, "originalRoute", this); 123 getAdviceWithTasks().add(AdviceWithTasks.replaceFrom(originalRoute, endpoint)); 124 } 125 126 /** 127 * Weaves by matching id of the nodes in the route. 128 * <p/> 129 * Uses the {@link org.apache.camel.util.EndpointHelper#matchPattern(String, String)} matching algorithm. 130 * 131 * @param pattern the pattern 132 * @return the builder 133 * @see org.apache.camel.util.EndpointHelper#matchPattern(String, String) 134 */ 135 public <T extends ProcessorDefinition<?>> AdviceWithBuilder<T> weaveById(String pattern) { 136 ObjectHelper.notNull(originalRoute, "originalRoute", this); 137 return new AdviceWithBuilder<T>(this, pattern, null, null); 138 } 139 140 /** 141 * Weaves by matching the to string representation of the nodes in the route. 142 * <p/> 143 * Uses the {@link org.apache.camel.util.EndpointHelper#matchPattern(String, String)} matching algorithm. 144 * 145 * @param pattern the pattern 146 * @return the builder 147 * @see org.apache.camel.util.EndpointHelper#matchPattern(String, String) 148 */ 149 public <T extends ProcessorDefinition<?>> AdviceWithBuilder<T> weaveByToString(String pattern) { 150 ObjectHelper.notNull(originalRoute, "originalRoute", this); 151 return new AdviceWithBuilder<T>(this, null, pattern, null); 152 } 153 154 /** 155 * Weaves by matching type of the nodes in the route. 156 * 157 * @param type the processor type 158 * @return the builder 159 */ 160 public <T extends ProcessorDefinition<?>> AdviceWithBuilder<T> weaveByType(Class<T> type) { 161 ObjectHelper.notNull(originalRoute, "originalRoute", this); 162 return new AdviceWithBuilder<T>(this, null, null, type); 163 } 164 165 /** 166 * Weaves by adding the nodes to the start of the route. 167 * 168 * @return the builder 169 */ 170 public <T extends ProcessorDefinition<?>> ProcessorDefinition<?> weaveAddFirst() { 171 ObjectHelper.notNull(originalRoute, "originalRoute", this); 172 return new AdviceWithBuilder<T>(this, "*", null, null).selectFirst().before(); 173 } 174 175 /** 176 * Weaves by adding the nodes to the end of the route. 177 * 178 * @return the builder 179 */ 180 public <T extends ProcessorDefinition<?>> ProcessorDefinition<?> weaveAddLast() { 181 ObjectHelper.notNull(originalRoute, "originalRoute", this); 182 return new AdviceWithBuilder<T>(this, "*", null, null).maxDeep(1).selectLast().after(); 183 } 184 185}