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.Iterator;
020import java.util.List;
021
022import javax.xml.bind.annotation.XmlAccessType;
023import javax.xml.bind.annotation.XmlAccessorType;
024import javax.xml.bind.annotation.XmlAttribute;
025import javax.xml.bind.annotation.XmlElement;
026import javax.xml.bind.annotation.XmlElementRef;
027import javax.xml.bind.annotation.XmlRootElement;
028import javax.xml.bind.annotation.XmlTransient;
029
030import org.apache.camel.spi.Metadata;
031
032@Metadata(label = "eip,routing,circuitbreaker")
033@XmlRootElement(name = "circuitBreaker")
034@XmlAccessorType(XmlAccessType.FIELD)
035public class CircuitBreakerDefinition extends OutputDefinition<CircuitBreakerDefinition> {
036
037    @XmlElement
038    private HystrixConfigurationDefinition hystrixConfiguration;
039    @XmlElement
040    private Resilience4jConfigurationDefinition resilience4jConfiguration;
041    @XmlElement
042    private FaultToleranceConfigurationDefinition faultToleranceConfiguration;
043    @XmlAttribute
044    private String configurationRef;
045    @XmlTransient
046    private OnFallbackDefinition onFallback;
047
048    public CircuitBreakerDefinition() {
049    }
050
051    @Override
052    public String toString() {
053        return "CircuitBreaker[" + getOutputs() + "]";
054    }
055
056    @Override
057    public String getShortName() {
058        return "circuitBreaker";
059    }
060
061    @Override
062    public String getLabel() {
063        return "circuitBreaker";
064    }
065
066    @Override
067    public List<ProcessorDefinition<?>> getOutputs() {
068        return outputs;
069    }
070
071    @XmlElementRef
072    @Override
073    public void setOutputs(List<ProcessorDefinition<?>> outputs) {
074        super.setOutputs(outputs);
075    }
076
077    @Override
078    public void addOutput(ProcessorDefinition<?> output) {
079        if (output instanceof OnFallbackDefinition) {
080            onFallback = (OnFallbackDefinition)output;
081        } else {
082            if (onFallback != null) {
083                onFallback.addOutput(output);
084            } else {
085                super.addOutput(output);
086            }
087        }
088    }
089
090    @Override
091    public ProcessorDefinition<?> end() {
092        if (onFallback != null) {
093            // end fallback as well
094            onFallback.end();
095        }
096        return super.end();
097    }
098
099    @Override
100    public void preCreateProcessor() {
101        // move the fallback from outputs to fallback which we need to ensure
102        // such as when using the XML DSL
103        Iterator<ProcessorDefinition<?>> it = outputs.iterator();
104        while (it.hasNext()) {
105            ProcessorDefinition<?> out = it.next();
106            if (out instanceof OnFallbackDefinition) {
107                onFallback = (OnFallbackDefinition)out;
108                it.remove();
109            }
110        }
111    }
112
113    // Getter/Setter
114    // -------------------------------------------------------------------------
115
116    @Deprecated
117    public HystrixConfigurationDefinition getHystrixConfiguration() {
118        return hystrixConfiguration;
119    }
120
121    @Deprecated
122    public void setHystrixConfiguration(HystrixConfigurationDefinition hystrixConfiguration) {
123        this.hystrixConfiguration = hystrixConfiguration;
124    }
125
126    public Resilience4jConfigurationCommon getResilience4jConfiguration() {
127        return resilience4jConfiguration;
128    }
129
130    public void setResilience4jConfiguration(Resilience4jConfigurationDefinition resilience4jConfiguration) {
131        this.resilience4jConfiguration = resilience4jConfiguration;
132    }
133
134    public FaultToleranceConfigurationDefinition getFaultToleranceConfiguration() {
135        return faultToleranceConfiguration;
136    }
137
138    public void setFaultToleranceConfiguration(FaultToleranceConfigurationDefinition faultToleranceConfiguration) {
139        this.faultToleranceConfiguration = faultToleranceConfiguration;
140    }
141
142    public String getConfigurationRef() {
143        return configurationRef;
144    }
145
146    /**
147     * Refers to a circuit breaker configuration (such as hystrix, resillience4j, or microprofile-fault-tolerance)
148     * to use for configuring the circuit breaker EIP.
149     */
150    public void setConfigurationRef(String configurationRef) {
151        this.configurationRef = configurationRef;
152    }
153
154    public OnFallbackDefinition getOnFallback() {
155        return onFallback;
156    }
157
158    public void setOnFallback(OnFallbackDefinition onFallback) {
159        this.onFallback = onFallback;
160    }
161
162    // Fluent API
163    // -------------------------------------------------------------------------
164
165    /**
166     * Configures the circuit breaker to use Hystrix.
167     * <p/>
168     * Use <tt>end</tt> when configuration is complete, to return back to the
169     * Circuit Breaker EIP.
170     */
171    @Deprecated
172    public HystrixConfigurationDefinition hystrixConfiguration() {
173        hystrixConfiguration = hystrixConfiguration == null ? new HystrixConfigurationDefinition(this) : hystrixConfiguration;
174        return hystrixConfiguration;
175    }
176
177    /**
178     * Configures the circuit breaker to use Hystrix with the given configuration.
179     */
180    @Deprecated
181    public CircuitBreakerDefinition hystrixConfiguration(HystrixConfigurationDefinition configuration) {
182        hystrixConfiguration = configuration;
183        return this;
184    }
185
186    /**
187     * Configures the circuit breaker to use Resilience4j.
188     * <p/>
189     * Use <tt>end</tt> when configuration is complete, to return back to the
190     * Circuit Breaker EIP.
191     */
192    public Resilience4jConfigurationDefinition resilience4jConfiguration() {
193        resilience4jConfiguration = resilience4jConfiguration == null ? new Resilience4jConfigurationDefinition(this) : resilience4jConfiguration;
194        return resilience4jConfiguration;
195    }
196
197    /**
198     * Configures the circuit breaker to use Resilience4j with the given configuration.
199     */
200    public CircuitBreakerDefinition resilience4jConfiguration(Resilience4jConfigurationDefinition configuration) {
201        resilience4jConfiguration = configuration;
202        return this;
203    }
204
205    /**
206     * Configures the circuit breaker to use MicroProfile Fault Tolerance.
207     * <p/>
208     * Use <tt>end</tt> when configuration is complete, to return back to the
209     * Circuit Breaker EIP.
210     */
211    public FaultToleranceConfigurationDefinition faultToleranceConfiguration() {
212        faultToleranceConfiguration = faultToleranceConfiguration == null ? new FaultToleranceConfigurationDefinition(this) : faultToleranceConfiguration;
213        return faultToleranceConfiguration;
214    }
215
216    /**
217     * Configures the circuit breaker to use MicroProfile Fault Tolerance with the given configuration.
218     */
219    public CircuitBreakerDefinition faultToleranceConfiguration(FaultToleranceConfigurationDefinition configuration) {
220        faultToleranceConfiguration = configuration;
221        return this;
222    }
223
224    /**
225     * Refers to a configuration to use for configuring the circuit breaker.
226     */
227    public CircuitBreakerDefinition configuration(String ref) {
228        configurationRef = ref;
229        return this;
230    }
231
232    /**
233     * The fallback route path to execute that does <b>not</b> go over
234     * the network.
235     * <p>
236     * This should be a static or cached result that can immediately be returned
237     * upon failure. If the fallback requires network connection then use
238     * {@link #onFallbackViaNetwork()}.
239     */
240    public CircuitBreakerDefinition onFallback() {
241        onFallback = new OnFallbackDefinition();
242        onFallback.setParent(this);
243        return this;
244    }
245
246    /**
247     * The fallback route path to execute that will go over the network.
248     * <p/>
249     * If the fallback will go over the network it is another possible point of failure.
250     */
251    public CircuitBreakerDefinition onFallbackViaNetwork() {
252        onFallback = new OnFallbackDefinition();
253        onFallback.setFallbackViaNetwork(Boolean.toString(true));
254        onFallback.setParent(this);
255        return this;
256    }
257
258}