/*
* Copyright 2014 Red Hat, Inc.
*
* Red Hat 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.
*/
/** @module vertx-circuit-breaker-js/circuit_breaker */
var utils = require('vertx-js/util/utils');
var Promise = require('vertx-js/promise');
var Vertx = require('vertx-js/vertx');
var Future = require('vertx-js/future');
var io = Packages.io;
var JsonObject = io.vertx.core.json.JsonObject;
var JsonArray = io.vertx.core.json.JsonArray;
var JCircuitBreaker = Java.type('io.vertx.circuitbreaker.CircuitBreaker');
var CircuitBreakerOptions = Java.type('io.vertx.circuitbreaker.CircuitBreakerOptions');
/**
An implementation of the circuit breaker pattern for Vert.x
@class
*/
var CircuitBreaker = function(j_val) {
var j_circuitBreaker = j_val;
var that = this;
var __super_create = this.create;
var __super_create = this.create;
var __super_close = this.close;
var __super_openHandler = this.openHandler;
var __super_halfOpenHandler = this.halfOpenHandler;
var __super_closeHandler = this.closeHandler;
var __super_executeWithFallback = this.executeWithFallback;
var __super_executeCommandWithFallback = this.executeCommandWithFallback;
var __super_execute = this.execute;
var __super_executeCommand = this.executeCommand;
var __super_executeAndReport = this.executeAndReport;
var __super_executeAndReportWithFallback = this.executeAndReportWithFallback;
var __super_fallback = this.fallback;
var __super_reset = this.reset;
var __super_open = this.open;
var __super_state = this.state;
var __super_failureCount = this.failureCount;
var __super_name = this.name;
var __super_retryPolicy = this.retryPolicy;
/**
Closes the circuit breaker. It stops sending events on its state on the event bus.
This method is not related to the <code>close</code> state of the circuit breaker. To set the circuit breaker in the
<code>close</code> state, use {@link CircuitBreaker#reset}.
@public
@return {CircuitBreaker}
*/
this.close = function() {
var __args = arguments;
if (__args.length === 0) {
j_circuitBreaker["close()"]() ;
return that;
} else if (typeof __super_close != 'undefined') {
return __super_close.apply(this, __args);
}
else throw new TypeError('function invoked with invalid arguments');
};
/**
Sets a invoked when the circuit breaker state switches to open.
@public
@param handler {function} the handler, must not be <code>null</code>
@return {CircuitBreaker} the current {@link CircuitBreaker}
*/
this.openHandler = function(handler) {
var __args = arguments;
if (__args.length === 1 && typeof __args[0] === 'function') {
j_circuitBreaker["openHandler(io.vertx.core.Handler)"](handler) ;
return that;
} else if (typeof __super_openHandler != 'undefined') {
return __super_openHandler.apply(this, __args);
}
else throw new TypeError('function invoked with invalid arguments');
};
/**
Sets a invoked when the circuit breaker state switches to half-open.
@public
@param handler {function} the handler, must not be <code>null</code>
@return {CircuitBreaker} the current {@link CircuitBreaker}
*/
this.halfOpenHandler = function(handler) {
var __args = arguments;
if (__args.length === 1 && typeof __args[0] === 'function') {
j_circuitBreaker["halfOpenHandler(io.vertx.core.Handler)"](handler) ;
return that;
} else if (typeof __super_halfOpenHandler != 'undefined') {
return __super_halfOpenHandler.apply(this, __args);
}
else throw new TypeError('function invoked with invalid arguments');
};
/**
Sets a invoked when the circuit breaker state switches to close.
@public
@param handler {function} the handler, must not be <code>null</code>
@return {CircuitBreaker} the current {@link CircuitBreaker}
*/
this.closeHandler = function(handler) {
var __args = arguments;
if (__args.length === 1 && typeof __args[0] === 'function') {
j_circuitBreaker["closeHandler(io.vertx.core.Handler)"](handler) ;
return that;
} else if (typeof __super_closeHandler != 'undefined') {
return __super_closeHandler.apply(this, __args);
}
else throw new TypeError('function invoked with invalid arguments');
};
/**
Executes the given operation with the circuit breaker control. The operation is generally calling an
<em>external</em> system. The operation receives a object as parameter and <strong>must</strong>
call when the operation has terminated successfully. The operation must also
call in case of failure.
<p>
The operation is not invoked if the circuit breaker is open, and the given fallback is called immediately. The
circuit breaker also monitor the completion of the operation before a configure timeout. The operation is
considered as failed if it does not terminate in time.
<p>
This method returns a object to retrieve the status and result of the operation, with the status
being a success or a failure. If the fallback is called, the returned future is successfully completed with the
value returned from the fallback. If the fallback throws an exception, the returned future is marked as failed.
@public
@param command {function} the operation
@param fallback {function} the fallback function. It gets an exception as parameter and returns the <em>fallback</em> result
@return {Future} a future object completed when the operation or its fallback completes
*/
this.executeWithFallback = function(command, fallback) {
var __args = arguments;
if (__args.length === 2 && typeof __args[0] === 'function' && typeof __args[1] === 'function') {
return utils.convReturnVertxGen(Future, j_circuitBreaker["executeWithFallback(io.vertx.core.Handler,java.util.function.Function)"](function(jVal) {
command(utils.convReturnVertxGen(Promise, jVal, undefined));
}, function(jVal) {
var jRet = fallback(utils.convReturnThrowable(jVal));
return utils.convParamTypeUnknown(jRet);
}), undefined) ;
} else if (typeof __super_executeWithFallback != 'undefined') {
return __super_executeWithFallback.apply(this, __args);
}
else throw new TypeError('function invoked with invalid arguments');
};
/**
Same as {@link CircuitBreaker#executeWithFallback} but using a callback.
@public
@param command {function} the operation
@param fallback {function} the fallback
@param handler {function} the completion handler receiving either the operation result or the fallback result. The parameter is an because if the fallback is not called, the error is passed to the handler.
*/
this.executeCommandWithFallback = function(command, fallback, handler) {
var __args = arguments;
if (__args.length === 3 && typeof __args[0] === 'function' && typeof __args[1] === 'function' && typeof __args[2] === 'function') {
j_circuitBreaker["executeCommandWithFallback(io.vertx.core.Handler,java.util.function.Function,io.vertx.core.Handler)"](function(jVal) {
command(utils.convReturnVertxGen(Promise, jVal, undefined));
}, function(jVal) {
var jRet = fallback(utils.convReturnThrowable(jVal));
return utils.convParamTypeUnknown(jRet);
}, function(ar) {
if (ar.succeeded()) {
handler(utils.convReturnTypeUnknown(ar.result()), null);
} else {
handler(null, ar.cause());
}
});
} else if (__args.length === 2 && typeof __args[0] === 'function' && typeof __args[1] === 'function') {
var __prom = Promise.promise();
var __prom_completer_handler = function (result, cause) { if (cause === null) { __prom.complete(result); } else { __prom.fail(cause); } };
j_circuitBreaker["executeCommandWithFallback(io.vertx.core.Handler,java.util.function.Function,io.vertx.core.Handler)"](function(jVal) {
command(utils.convReturnVertxGen(Promise, jVal, undefined));
}, function(jVal) {
var jRet = fallback(utils.convReturnThrowable(jVal));
return utils.convParamTypeUnknown(jRet);
}, function(ar) {
if (ar.succeeded()) {
__prom_completer_handler(utils.convReturnTypeUnknown(ar.result()), null);
} else {
__prom_completer_handler(null, ar.cause());
}
});
return __prom.future();
} else if (typeof __super_executeCommandWithFallback != 'undefined') {
return __super_executeCommandWithFallback.apply(this, __args);
}
else throw new TypeError('function invoked with invalid arguments');
};
/**
Same as {@link CircuitBreaker#executeWithFallback} but using the circuit breaker default fallback.
@public
@param command {function} the operation
@return {Future} a future object completed when the operation or its fallback completes
*/
this.execute = function(command) {
var __args = arguments;
if (__args.length === 1 && typeof __args[0] === 'function') {
return utils.convReturnVertxGen(Future, j_circuitBreaker["execute(io.vertx.core.Handler)"](function(jVal) {
command(utils.convReturnVertxGen(Promise, jVal, undefined));
}), undefined) ;
} else if (typeof __super_execute != 'undefined') {
return __super_execute.apply(this, __args);
}
else throw new TypeError('function invoked with invalid arguments');
};
/**
Same as {@link CircuitBreaker#executeWithFallback} but using the circuit breaker default fallback.
@public
@param command {function} the operation
@param handler {function} the completion handler receiving either the operation result or the fallback result. The parameter is an because if the fallback is not called, the error is passed to the handler.
*/
this.executeCommand = function(command, handler) {
var __args = arguments;
if (__args.length === 2 && typeof __args[0] === 'function' && typeof __args[1] === 'function') {
j_circuitBreaker["executeCommand(io.vertx.core.Handler,io.vertx.core.Handler)"](function(jVal) {
command(utils.convReturnVertxGen(Promise, jVal, undefined));
}, function(ar) {
if (ar.succeeded()) {
handler(utils.convReturnTypeUnknown(ar.result()), null);
} else {
handler(null, ar.cause());
}
});
} else if (__args.length === 1 && typeof __args[0] === 'function') {
var __prom = Promise.promise();
var __prom_completer_handler = function (result, cause) { if (cause === null) { __prom.complete(result); } else { __prom.fail(cause); } };
j_circuitBreaker["executeCommand(io.vertx.core.Handler,io.vertx.core.Handler)"](function(jVal) {
command(utils.convReturnVertxGen(Promise, jVal, undefined));
}, function(ar) {
if (ar.succeeded()) {
__prom_completer_handler(utils.convReturnTypeUnknown(ar.result()), null);
} else {
__prom_completer_handler(null, ar.cause());
}
});
return __prom.future();
} else if (typeof __super_executeCommand != 'undefined') {
return __super_executeCommand.apply(this, __args);
}
else throw new TypeError('function invoked with invalid arguments');
};
/**
Same as {@link CircuitBreaker#executeAndReportWithFallback} but using the circuit breaker default
fallback.
@public
@param resultPromise {Promise} the promise on which the operation result is reported
@param command {function} the operation
@return {CircuitBreaker} the current {@link CircuitBreaker}
*/
this.executeAndReport = function(resultPromise, command) {
var __args = arguments;
if (__args.length === 2 && typeof __args[0] === 'object' && __args[0]._jdel && typeof __args[1] === 'function') {
j_circuitBreaker["executeAndReport(io.vertx.core.Promise,io.vertx.core.Handler)"](resultPromise._jdel, function(jVal) {
command(utils.convReturnVertxGen(Promise, jVal, undefined));
}) ;
return that;
} else if (typeof __super_executeAndReport != 'undefined') {
return __super_executeAndReport.apply(this, __args);
}
else throw new TypeError('function invoked with invalid arguments');
};
/**
Executes the given operation with the circuit breaker control. The operation is generally calling an
<em>external</em> system. The operation receives a object as parameter and <strong>must</strong>
call when the operation has terminated successfully. The operation must also
call in case of failure.
<p>
The operation is not invoked if the circuit breaker is open, and the given fallback is called immediately. The
circuit breaker also monitor the completion of the operation before a configure timeout. The operation is
considered as failed if it does not terminate in time.
<p>
Unlike {@link CircuitBreaker#executeWithFallback}, this method does return a object, but
let the caller pass a object on which the result is reported. If the fallback is called, the future
is successfully completed with the value returned by the fallback function. If the fallback throws an exception,
the future is marked as failed.
@public
@param resultPromise {Promise} the promise on which the operation result is reported
@param command {function} the operation
@param fallback {function} the fallback function. It gets an exception as parameter and returns the <em>fallback</em> result
@return {CircuitBreaker} the current {@link CircuitBreaker}
*/
this.executeAndReportWithFallback = function(resultPromise, command, fallback) {
var __args = arguments;
if (__args.length === 3 && typeof __args[0] === 'object' && __args[0]._jdel && typeof __args[1] === 'function' && typeof __args[2] === 'function') {
j_circuitBreaker["executeAndReportWithFallback(io.vertx.core.Promise,io.vertx.core.Handler,java.util.function.Function)"](resultPromise._jdel, function(jVal) {
command(utils.convReturnVertxGen(Promise, jVal, undefined));
}, function(jVal) {
var jRet = fallback(utils.convReturnThrowable(jVal));
return utils.convParamTypeUnknown(jRet);
}) ;
return that;
} else if (typeof __super_executeAndReportWithFallback != 'undefined') {
return __super_executeAndReportWithFallback.apply(this, __args);
}
else throw new TypeError('function invoked with invalid arguments');
};
/**
Sets a <em>default</em> invoked when the bridge is open to handle the "request", or on failure
if <a href="../../dataobjects.html#CircuitBreakerOptions">CircuitBreakerOptions</a> is enabled.
<p>
The function gets the exception as parameter and returns the <em>fallback</em> result.
@public
@param handler {function} the handler
@return {CircuitBreaker} the current {@link CircuitBreaker}
*/
this.fallback = function(handler) {
var __args = arguments;
if (__args.length === 1 && typeof __args[0] === 'function') {
j_circuitBreaker["fallback(java.util.function.Function)"](function(jVal) {
var jRet = handler(utils.convReturnThrowable(jVal));
return utils.convParamTypeUnknown(jRet);
}) ;
return that;
} else if (typeof __super_fallback != 'undefined') {
return __super_fallback.apply(this, __args);
}
else throw new TypeError('function invoked with invalid arguments');
};
/**
Resets the circuit breaker state (number of failure set to 0 and state set to closed).
@public
@return {CircuitBreaker} the current {@link CircuitBreaker}
*/
this.reset = function() {
var __args = arguments;
if (__args.length === 0) {
j_circuitBreaker["reset()"]() ;
return that;
} else if (typeof __super_reset != 'undefined') {
return __super_reset.apply(this, __args);
}
else throw new TypeError('function invoked with invalid arguments');
};
/**
Explicitly opens the circuit.
@public
@return {CircuitBreaker} the current {@link CircuitBreaker}
*/
this.open = function() {
var __args = arguments;
if (__args.length === 0) {
j_circuitBreaker["open()"]() ;
return that;
} else if (typeof __super_open != 'undefined') {
return __super_open.apply(this, __args);
}
else throw new TypeError('function invoked with invalid arguments');
};
/**
@public
@return {Object} the current state.
*/
this.state = function() {
var __args = arguments;
if (__args.length === 0) {
return utils.convReturnEnum(j_circuitBreaker["state()"]()) ;
} else if (typeof __super_state != 'undefined') {
return __super_state.apply(this, __args);
}
else throw new TypeError('function invoked with invalid arguments');
};
/**
@public
@return {number} the current number of failures.
*/
this.failureCount = function() {
var __args = arguments;
if (__args.length === 0) {
return j_circuitBreaker["failureCount()"]() ;
} else if (typeof __super_failureCount != 'undefined') {
return __super_failureCount.apply(this, __args);
}
else throw new TypeError('function invoked with invalid arguments');
};
/**
@public
@return {string} the name of the circuit breaker.
*/
this.name = function() {
var __args = arguments;
if (__args.length === 0) {
if (that.cachedname == null) {
that.cachedname = j_circuitBreaker["name()"]();
}
return that.cachedname;
} else if (typeof __super_name != 'undefined') {
return __super_name.apply(this, __args);
}
else throw new TypeError('function invoked with invalid arguments');
};
/**
@public
@param retryPolicy {function}
@return {CircuitBreaker}
*/
this.retryPolicy = function(retryPolicy) {
var __args = arguments;
if (__args.length === 1 && typeof __args[0] === 'function') {
j_circuitBreaker["retryPolicy(java.util.function.Function)"](function(jVal) {
var jRet = retryPolicy(jVal);
return utils.convParamLong(jRet);
}) ;
return that;
} else if (typeof __super_retryPolicy != 'undefined') {
return __super_retryPolicy.apply(this, __args);
}
else throw new TypeError('function invoked with invalid arguments');
};
// A reference to the underlying Java delegate
// NOTE! This is an internal API and must not be used in user code.
// If you rely on this property your code is likely to break if we change it / remove it without warning.
this._jdel = j_circuitBreaker;
};
CircuitBreaker._jclass = utils.getJavaClass("io.vertx.circuitbreaker.CircuitBreaker");
CircuitBreaker._jtype = {accept: function(obj) {
return CircuitBreaker._jclass.isInstance(obj._jdel);
},wrap: function(jdel) {
var obj = Object.create(CircuitBreaker.prototype, {});
CircuitBreaker.apply(obj, arguments);
return obj;
},
unwrap: function(obj) {
return obj._jdel;
}
};
CircuitBreaker._create = function(jdel) {var obj = Object.create(CircuitBreaker.prototype, {});
CircuitBreaker.apply(obj, arguments);
return obj;
}
/**
Creates a new instance of {@link CircuitBreaker}, with default options.
@memberof module:vertx-circuit-breaker-js/circuit_breaker
@param name {string} the name
@param vertx {Vertx} the Vert.x instance
@return {CircuitBreaker} the created instance
*/
CircuitBreaker.create = function() {
var __args = arguments;
if (__args.length === 3 && typeof __args[0] === 'string' && typeof __args[1] === 'object' && __args[1]._jdel && (typeof __args[2] === 'object' && __args[2] != null)) {
return utils.convReturnVertxGen(CircuitBreaker, JCircuitBreaker["create(java.lang.String,io.vertx.core.Vertx,io.vertx.circuitbreaker.CircuitBreakerOptions)"](__args[0], __args[1]._jdel, __args[2] != null ? new CircuitBreakerOptions(new JsonObject(Java.asJSONCompatible(__args[2]))) : null)) ;
} else if (__args.length === 2 && typeof __args[0] === 'string' && typeof __args[1] === 'object' && __args[1]._jdel) {
return utils.convReturnVertxGen(CircuitBreaker, JCircuitBreaker["create(java.lang.String,io.vertx.core.Vertx)"](__args[0], __args[1]._jdel)) ;
}else throw new TypeError('function invoked with invalid arguments');
};
module.exports = CircuitBreaker;