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.model; 018 019import java.util.ArrayList; 020import java.util.Iterator; 021import java.util.List; 022 023import javax.xml.bind.annotation.XmlAccessType; 024import javax.xml.bind.annotation.XmlAccessorType; 025import javax.xml.bind.annotation.XmlAttribute; 026import javax.xml.bind.annotation.XmlElement; 027import javax.xml.bind.annotation.XmlElementRef; 028import javax.xml.bind.annotation.XmlRootElement; 029import javax.xml.bind.annotation.XmlTransient; 030 031import org.apache.camel.spi.Metadata; 032 033/** 034 * Hystrix Circuit Breaker EIP 035 */ 036@Metadata(label = "eip,routing,circuitbreaker") 037@XmlRootElement(name = "hystrix") 038@XmlAccessorType(XmlAccessType.FIELD) 039public class HystrixDefinition extends ProcessorDefinition<HystrixDefinition> implements OutputNode { 040 041 @XmlElement 042 private HystrixConfigurationDefinition hystrixConfiguration; 043 @XmlElementRef 044 private List<ProcessorDefinition<?>> outputs = new ArrayList<>(); 045 @XmlTransient 046 private OnFallbackDefinition onFallback; 047 @XmlAttribute 048 private String hystrixConfigurationRef; 049 050 public HystrixDefinition() { 051 } 052 053 @Override 054 public String toString() { 055 return "Hystrix[" + getOutputs() + "]"; 056 } 057 058 @Override 059 public String getShortName() { 060 return "hystrix"; 061 } 062 063 @Override 064 public String getLabel() { 065 return "hystrix"; 066 } 067 068 @Override 069 public List<ProcessorDefinition<?>> getOutputs() { 070 return outputs; 071 } 072 073 public void setOutputs(List<ProcessorDefinition<?>> outputs) { 074 this.outputs = outputs; 075 if (outputs != null) { 076 for (ProcessorDefinition<?> output : outputs) { 077 configureChild(output); 078 } 079 } 080 } 081 082 @Override 083 public void addOutput(ProcessorDefinition<?> output) { 084 if (output instanceof OnFallbackDefinition) { 085 onFallback = (OnFallbackDefinition)output; 086 } else { 087 if (onFallback != null) { 088 onFallback.addOutput(output); 089 } else { 090 super.addOutput(output); 091 } 092 } 093 } 094 095 @Override 096 public ProcessorDefinition<?> end() { 097 if (onFallback != null) { 098 // end fallback as well 099 onFallback.end(); 100 } 101 return super.end(); 102 } 103 104 @Override 105 public void preCreateProcessor() { 106 // move the fallback from outputs to fallback which we need to ensure 107 // such as when using the XML DSL 108 Iterator<ProcessorDefinition<?>> it = outputs.iterator(); 109 while (it.hasNext()) { 110 ProcessorDefinition<?> out = it.next(); 111 if (out instanceof OnFallbackDefinition) { 112 onFallback = (OnFallbackDefinition)out; 113 it.remove(); 114 } 115 } 116 } 117 118 // Getter/Setter 119 // ------------------------------------------------------------------------- 120 121 public HystrixConfigurationDefinition getHystrixConfiguration() { 122 return hystrixConfiguration; 123 } 124 125 public void setHystrixConfiguration(HystrixConfigurationDefinition hystrixConfiguration) { 126 this.hystrixConfiguration = hystrixConfiguration; 127 } 128 129 public String getHystrixConfigurationRef() { 130 return hystrixConfigurationRef; 131 } 132 133 /** 134 * Refers to a Hystrix configuration to use for configuring the Hystrix EIP. 135 */ 136 public void setHystrixConfigurationRef(String hystrixConfigurationRef) { 137 this.hystrixConfigurationRef = hystrixConfigurationRef; 138 } 139 140 public OnFallbackDefinition getOnFallback() { 141 return onFallback; 142 } 143 144 public void setOnFallback(OnFallbackDefinition onFallback) { 145 this.onFallback = onFallback; 146 } 147 148 // Fluent API 149 // ------------------------------------------------------------------------- 150 151 /** 152 * Sets the group key to use. The default value is CamelHystrix. 153 */ 154 public HystrixDefinition groupKey(String groupKey) { 155 hystrixConfiguration().groupKey(groupKey); 156 return this; 157 } 158 159 /** 160 * Sets the thread pool key to use. The default value is CamelHystrix. 161 */ 162 public HystrixDefinition threadPoolKey(String threadPoolKey) { 163 hystrixConfiguration().threadPoolKey(threadPoolKey); 164 return this; 165 } 166 167 /** 168 * Configures the Hystrix EIP 169 * <p/> 170 * Use <tt>end</tt> when configuration is complete, to return back to the 171 * Hystrix EIP. 172 */ 173 public HystrixConfigurationDefinition hystrixConfiguration() { 174 hystrixConfiguration = hystrixConfiguration == null ? new HystrixConfigurationDefinition(this) : hystrixConfiguration; 175 return hystrixConfiguration; 176 } 177 178 /** 179 * Configures the Hystrix EIP using the given configuration 180 */ 181 public HystrixDefinition hystrixConfiguration(HystrixConfigurationDefinition configuration) { 182 hystrixConfiguration = configuration; 183 return this; 184 } 185 186 /** 187 * Refers to a Hystrix configuration to use for configuring the Hystrix EIP. 188 */ 189 public HystrixDefinition hystrixConfiguration(String ref) { 190 hystrixConfigurationRef = ref; 191 return this; 192 } 193 194 /** 195 * The Hystrix fallback route path to execute that does <b>not</b> go over 196 * the network. 197 * <p> 198 * This should be a static or cached result that can immediately be returned 199 * upon failure. If the fallback requires network connection then use 200 * {@link #onFallbackViaNetwork()}. 201 */ 202 public HystrixDefinition onFallback() { 203 onFallback = new OnFallbackDefinition(); 204 onFallback.setParent(this); 205 return this; 206 } 207 208 /** 209 * The Hystrix fallback route path to execute that will go over the network. 210 * <p/> 211 * If the fallback will go over the network it is another possible point of 212 * failure and so it also needs to be wrapped by a HystrixCommand. It is 213 * important to execute the fallback command on a separate thread-pool, 214 * otherwise if the main command were to become latent and fill the 215 * thread-pool this would prevent the fallback from running if the two 216 * commands share the same pool. 217 */ 218 public HystrixDefinition onFallbackViaNetwork() { 219 onFallback = new OnFallbackDefinition(); 220 onFallback.setFallbackViaNetwork(true); 221 onFallback.setParent(this); 222 return this; 223 } 224 225}