Skip to content

Commit

Permalink
feat(RESTConnector): add option to throw exception when http status i…
Browse files Browse the repository at this point in the history
…s error

if a response status code is not >= 200 or <400 will throw an exception if user checks the new "Throw on error status" checkbox.
  • Loading branch information
marcioluis committed Sep 27, 2024
1 parent 5ef09a0 commit 1034f8b
Show file tree
Hide file tree
Showing 38 changed files with 134 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public abstract class AbstractRESTConnectorImpl extends AbstractConnector {
protected static final String METHOD_INPUT_PARAMETER = "method";
protected static final String CONTENTTYPE_INPUT_PARAMETER = "contentType";
protected static final String CHARSET_INPUT_PARAMETER = "charset";
protected static final String THROW_ON_ERROR_INPUT_PARAMETER = "throwOnErrorStatus";
protected static final String URLCOOKIES_INPUT_PARAMETER = "urlCookies";
protected static final String URLHEADERS_INPUT_PARAMETER = "urlHeaders";
protected static final String DOCUMENT_BODY_INPUT_PARAMETER = "documentBody";
Expand Down Expand Up @@ -80,6 +81,11 @@ protected final String getCharset() {
return (java.lang.String) getInputParameter(CHARSET_INPUT_PARAMETER);
}

protected final Boolean getThrowOnErrorStatus() {
final Boolean throwOnError = (Boolean) getInputParameter(THROW_ON_ERROR_INPUT_PARAMETER);
return throwOnError != null ? throwOnError : Boolean.FALSE;
}

@SuppressWarnings("unchecked")
protected final List<List<?>> getUrlCookies() {
List<List<?>> cookies = (List<List<?>>) getInputParameter(URLCOOKIES_INPUT_PARAMETER);
Expand Down Expand Up @@ -478,6 +484,14 @@ void validateCharset() throws ConnectorValidationException {
}
}

void validateThrowOnError() throws ConnectorValidationException {
try {
getThrowOnErrorStatus();
} catch (final ClassCastException cce) {
throw new ConnectorValidationException("throwOnErrorStatus type is invalid");
}
}

void validateContentType() throws ConnectorValidationException {
try {
getContentType();
Expand Down
10 changes: 9 additions & 1 deletion src/main/java/org/bonitasoft/connectors/rest/RESTConnector.java
Original file line number Diff line number Diff line change
Expand Up @@ -571,12 +571,20 @@ public void execute(final Request request) throws Exception {
final CloseableHttpResponse httpResponse = httpClient.execute(httpRequest, httpContext);
LOGGER.fine("Response recieved.");
final int statusCode = httpResponse.getStatusLine().getStatusCode();
final String reasonPhrase = httpResponse.getStatusLine().getReasonPhrase();

if (!statusSuccessful(statusCode)) {
LOGGER.warning(
() -> String.format(
"%s response status is not successful: %s - %s",
request, statusCode, httpResponse.getStatusLine().getReasonPhrase()));
request, statusCode, reasonPhrase));

if(Boolean.TRUE.equals(getThrowOnErrorStatus())){
throw new ConnectorException(
String.format("%s response status is not successful: %s - %s", request, statusCode, reasonPhrase));
}
}

setOutputs(httpResponse, request);
} finally {
try {
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources-filtered/rest-delete.def
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
<input name="socket_timeout_ms" type="java.lang.Integer" defaultValue="60000"/>
<input name="connection_timeout_ms" type="java.lang.Integer" defaultValue="60000"/>
<input name="trust_strategy" type="java.lang.String" mandatory="false" defaultValue="DEFAULT"/>
<input name="throwOnErrorStatus" type="java.lang.Boolean" mandatory="false"/>

<!-- outputs -->
<output name="bodyAsString" type="java.lang.String"/>
Expand All @@ -43,6 +44,7 @@
<!-- pages -->
<page id="RESTConnectorWizardPage">
<widget xsi:type="definition:Text" id="urlWidget" inputName="url"/>
<widget xsi:type="definition:Checkbox" id="throwOnErrorStatusWidget" inputName="throwOnErrorStatus"/>
</page>
<page id="Advanced">
<widget xsi:type="definition:Array" id="urlHeadersWidget" inputName="urlHeaders" cols="2" fixedCols="true">
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources-filtered/rest-file-post.def
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
<input name="socket_timeout_ms" type="java.lang.Integer" defaultValue="60000"/>
<input name="connection_timeout_ms" type="java.lang.Integer" defaultValue="60000"/>
<input name="trust_strategy" type="java.lang.String" mandatory="false" defaultValue="DEFAULT"/>
<input name="throwOnErrorStatus" type="java.lang.Boolean" mandatory="false"/>

<!-- outputs -->
<output name="bodyAsString" type="java.lang.String"/>
Expand All @@ -54,6 +55,7 @@
<items>text/plain</items>
<items>text/xml</items>
</widget>
<widget xsi:type="definition:Checkbox" id="throwOnErrorStatusWidget" inputName="throwOnErrorStatus"/>
<widget xsi:type="definition:Text" id="charsetWidget" inputName="charset"/>
<widget xsi:type="definition:Text" id="documentBodyWidget" inputName="documentBody" showDocuments="true" />
</page>
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources-filtered/rest-file-put.def
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
<input name="socket_timeout_ms" type="java.lang.Integer" defaultValue="60000"/>
<input name="connection_timeout_ms" type="java.lang.Integer" defaultValue="60000"/>
<input name="trust_strategy" type="java.lang.String" mandatory="false" defaultValue="DEFAULT"/>
<input name="throwOnErrorStatus" type="java.lang.Boolean" mandatory="false"/>

<!-- outputs -->
<output name="bodyAsString" type="java.lang.String"/>
Expand All @@ -54,6 +55,7 @@
<items>text/plain</items>
<items>text/xml</items>
</widget>
<widget xsi:type="definition:Checkbox" id="throwOnErrorStatusWidget" inputName="throwOnErrorStatus"/>
<widget xsi:type="definition:Text" id="charsetWidget" inputName="charset"/>
<widget xsi:type="definition:Text" id="documentBodyWidget" inputName="documentBody" showDocuments="true" />
</page>
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources-filtered/rest-get.def
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
<input name="socket_timeout_ms" type="java.lang.Integer" defaultValue="60000"/>
<input name="connection_timeout_ms" type="java.lang.Integer" defaultValue="60000"/>
<input name="trust_strategy" type="java.lang.String" mandatory="false" defaultValue="DEFAULT"/>
<input name="throwOnErrorStatus" type="java.lang.Boolean" mandatory="false"/>

<!-- outputs -->
<output name="bodyAsString" type="java.lang.String"/>
Expand All @@ -43,6 +44,7 @@
<!-- pages -->
<page id="RESTConnectorWizardPage">
<widget xsi:type="definition:Text" id="urlWidget" inputName="url"/>
<widget xsi:type="definition:Checkbox" id="throwOnErrorStatusWidget" inputName="throwOnErrorStatus"/>
</page>
<page id="Advanced">
<widget xsi:type="definition:Array" id="urlHeadersWidget" inputName="urlHeaders" cols="2" fixedCols="true">
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources-filtered/rest-head.def
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
<input name="socket_timeout_ms" type="java.lang.Integer" defaultValue="60000"/>
<input name="connection_timeout_ms" type="java.lang.Integer" defaultValue="60000"/>
<input name="trust_strategy" type="java.lang.String" mandatory="false" defaultValue="DEFAULT"/>
<input name="throwOnErrorStatus" type="java.lang.Boolean" mandatory="false"/>

<!-- outputs -->

Expand All @@ -42,6 +43,7 @@
<!-- pages -->
<page id="RESTConnectorWizardPage">
<widget xsi:type="definition:Text" id="urlWidget" inputName="url"/>
<widget xsi:type="definition:Checkbox" id="throwOnErrorStatusWidget" inputName="throwOnErrorStatus"/>
</page>
<page id="Advanced">
<widget xsi:type="definition:Array" id="urlHeadersWidget" inputName="urlHeaders" cols="2" fixedCols="true">
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources-filtered/rest-post.def
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
<input name="socket_timeout_ms" type="java.lang.Integer" defaultValue="60000"/>
<input name="connection_timeout_ms" type="java.lang.Integer" defaultValue="60000"/>
<input name="trust_strategy" type="java.lang.String" mandatory="false" defaultValue="DEFAULT"/>
<input name="throwOnErrorStatus" type="java.lang.Boolean" mandatory="false"/>

<!-- outputs -->
<output name="bodyAsString" type="java.lang.String"/>
Expand All @@ -55,6 +56,7 @@
<items>text/plain</items>
<items>text/xml</items>
</widget>
<widget xsi:type="definition:Checkbox" id="throwOnErrorStatusWidget" inputName="throwOnErrorStatus"/>
<widget xsi:type="definition:Text" id="charsetWidget" inputName="charset"/>
<widget xsi:type="definition:TextArea" id="bodyWidget" inputName="body"/>
</page>
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources-filtered/rest-put.def
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
<input name="socket_timeout_ms" type="java.lang.Integer" defaultValue="60000"/>
<input name="connection_timeout_ms" type="java.lang.Integer" defaultValue="60000"/>
<input name="trust_strategy" type="java.lang.String" mandatory="false" defaultValue="DEFAULT"/>
<input name="throwOnErrorStatus" type="java.lang.Boolean" mandatory="false"/>

<!-- outputs -->
<output name="bodyAsString" type="java.lang.String"/>
Expand All @@ -55,6 +56,7 @@
<items>text/plain</items>
<items>text/xml</items>
</widget>
<widget xsi:type="definition:Checkbox" id="throwOnErrorStatusWidget" inputName="throwOnErrorStatus"/>
<widget xsi:type="definition:Text" id="charsetWidget" inputName="charset"/>
<widget xsi:type="definition:TextArea" id="bodyWidget" inputName="body"/>
</page>
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/rest-delete.properties
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,5 @@ proxy_password_widget.label=Password
outputsDescription=If the response Content-Type is Json compatible, use the 'bodyAsObject' output to quickly access your data in a script (e.g: bodyAsObject.user.name, or, in the case of an array, bodyAsObject[0].user.name), use the 'bodyAsString' output otherwise.
socket_timeout_ms_widget.label=Socket timeout
connection_timeout_ms_widget.label=Connection timeout
throwOnErrorStatusWidget.description=If checked, no outputs will be sent, and an error will be thrown if the status code is not between 200 and 399.
throwOnErrorStatusWidget.label=Throw on error status
2 changes: 2 additions & 0 deletions src/main/resources/rest-delete_es.properties
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,5 @@ proxy_username_widget.description=El nombre de usuario si se requiere autenticac
proxy_password_widget.label=Contraseña
proxy_password_widget.description=La contraseña si se requiere autenticación desde el servidor proxy
outputsDescription=Si la respuesta Content-Type es compatible con Json, usa la salida 'bodyAsObject' para acceder rápidamente a los datos en un script (ejemplo: bodyAsObject.user.name o, en el caso de un Array, bodyAsObject[0].userName). Si no es compatible, usa la salida 'bodyAsString'.
throwOnErrorStatusWidget.description=Si se selecciona, no se enviará ninguna salida y se generará un error si el código de estado no está entre 200 y 399.
throwOnErrorStatusWidget.label=Lanzar en el estado de error
2 changes: 2 additions & 0 deletions src/main/resources/rest-delete_fr.properties
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,5 @@ proxy_password_widget.label=Mot de passe
Advanced.pageTitle=Paramètres avancés (optionnel)
Advanced.pageDescription=Saisissez les paramètres avancés du connecteur REST.
outputsDescription=Si le Content-Type (type de contenu) de la réponse est compatible avec JSON, utilisez la sortie 'bodyAsObject' pour accéder rapidement à vos données dans un script (e.g: bodyAsObject.user.name, ou, dans le cas d'un tableau, bodyAsObject[0].user.name), sinon utilisez la sortie 'bodyAsString'.
throwOnErrorStatusWidget.description=Si cette case est cochée, aucune sortie n'est envoyée et une erreur est générée si le code d'état n'est pas compris entre 200 et 399
throwOnErrorStatusWidget.label=Activer l'état d'erreur
2 changes: 2 additions & 0 deletions src/main/resources/rest-delete_ja.properties
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,5 @@ proxy_username_widget.label=ユーザー名
proxy_password_widget.label=パスワード
#proxy_password_widget.description=プロキシ・サーバーから認証が要求される場合のパスワード
outputsDescription=レスポンスの Content-Type が JSON 互換の場合、スクリプトでデータを素早くアクセスするには、'bodyAsObject' output (例: bodyAsObject.user.name または bodyAsObject[0].userName)を使用します。その他の場合は、'bodyAsString' output を使用します。
throwOnErrorStatusWidget.description=チェックされている場合、出力は送信されず、ステータスコードが200から399の間でない場合はエラーが発生します。
throwOnErrorStatusWidget.label=エラーステータスをスローする
2 changes: 2 additions & 0 deletions src/main/resources/rest-file-post.properties
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,5 @@ proxy_password_widget.label=Password
outputsDescription=If the response Content-Type is Json compatible, use the 'bodyAsObject' output to quickly access your data in a script (e.g: bodyAsObject.user.name, or, in the case of an array, bodyAsObject[0].user.name), use the 'bodyAsString' output otherwise.
socket_timeout_ms_widget.label=Socket timeout
connection_timeout_ms_widget.label=Connection timeout
throwOnErrorStatusWidget.description=If checked, no outputs will be sent, and an error will be thrown if the status code is not between 200 and 399.
throwOnErrorStatusWidget.label=Throw on error status
2 changes: 2 additions & 0 deletions src/main/resources/rest-file-post_es.properties
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,5 @@ proxy_username_widget.label=Usuario
proxy_password_widget.label=Contraseña
#proxy_password_widget.description=La contraseña si se requiere autenticación desde el servidor proxy
outputsDescription=Si la respuesta Content-Type es compatible con Json, usa la salida 'bodyAsObject' para acceder rápidamente a los datos en un script (ejemplo: bodyAsObject.user.name o, en el caso de un Array, bodyAsObject[0].userName). Si no es compatible, usa la salida 'bodyAsString'.
throwOnErrorStatusWidget.description=Si se selecciona, no se enviará ninguna salida y se generará un error si el código de estado no está entre 200 y 399.
throwOnErrorStatusWidget.label=Lanzar en el estado de error
3 changes: 2 additions & 1 deletion src/main/resources/rest-file-post_fr.properties
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,5 @@ proxy_password_widget.label=Mot de passe
Advanced.pageTitle=Paramètres avancés (optionnel)
Advanced.pageDescription=Saisissez les paramètres avancés du connecteur REST.
outputsDescription=Si le Content-Type (type de contenu) de la réponse est compatible avec JSON, utilisez la sortie 'bodyAsObject' pour accéder rapidement à vos données dans un script (e.g: bodyAsObject.user.name, ou, dans le cas d'un tableau, bodyAsObject[0].user.name), sinon utilisez la sortie 'bodyAsString'.

throwOnErrorStatusWidget.description=Si cette case est cochée, aucune sortie n'est envoyée et une erreur est générée si le code d'état n'est pas compris entre 200 et 399
throwOnErrorStatusWidget.label=Activer l'état d'erreur
2 changes: 2 additions & 0 deletions src/main/resources/rest-file-post_ja.properties
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,5 @@ proxy_username_widget.label=ユーザー名
proxy_password_widget.label=パスワード
#proxy_password_widget.description=プロキシ・サーバーから認証が要求される場合のパスワード
outputsDescription=レスポンスの Content-Type が JSON 互換の場合、スクリプトでデータを素早くアクセスするには、'bodyAsObject' output (例: bodyAsObject.user.name または bodyAsObject[0].userName)を使用します。その他の場合は、'bodyAsString' output を使用します。
throwOnErrorStatusWidget.description=チェックされている場合、出力は送信されず、ステータスコードが200から399の間でない場合はエラーが発生します。
throwOnErrorStatusWidget.label=エラーステータスをスローする
2 changes: 2 additions & 0 deletions src/main/resources/rest-file-put.properties
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,5 @@ proxy_password_widget.label=Password
outputsDescription=If the response Content-Type is Json compatible, use the 'bodyAsObject' output to quickly access your data in a script (e.g: bodyAsObject.user.name, or, in the case of an array, bodyAsObject[0].user.name), use the 'bodyAsString' output otherwise.
socket_timeout_ms_widget.label=Socket timeout
connection_timeout_ms_widget.label=Connection timeout
throwOnErrorStatusWidget.description=If checked, no outputs will be sent, and an error will be thrown if the status code is not between 200 and 399.
throwOnErrorStatusWidget.label=Throw on error status
2 changes: 2 additions & 0 deletions src/main/resources/rest-file-put_es.properties
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,5 @@ proxy_username_widget.description=El nombre de usuario si se requiere autenticac
proxy_password_widget.label=Contraseña
proxy_password_widget.description=La contraseña si se requiere autenticación desde el servidor proxy
outputsDescription=Si la respuesta Content-Type es compatible con Json, usa la salida 'bodyAsObject' para acceder rápidamente a los datos en un script (ejemplo: bodyAsObject.user.name o, en el caso de un Array, bodyAsObject[0].userName). Si no es compatible, usa la salida 'bodyAsString'.
throwOnErrorStatusWidget.description=Si se selecciona, no se enviará ninguna salida y se generará un error si el código de estado no está entre 200 y 399.
throwOnErrorStatusWidget.label=Lanzar en el estado de error
3 changes: 2 additions & 1 deletion src/main/resources/rest-file-put_fr.properties
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,5 @@ proxy_password_widget.label=Mot de passe
Advanced.pageTitle=Paramètres avancés (optionnel)
Advanced.pageDescription=Saisissez les paramètres avancés du connecteur REST.
outputsDescription=Si le Content-Type (type de contenu) de la réponse est compatible avec JSON, utilisez la sortie 'bodyAsObject' pour accéder rapidement à vos données dans un script (e.g: bodyAsObject.user.name, ou, dans le cas d'un tableau, bodyAsObject[0].user.name), sinon utilisez la sortie 'bodyAsString'.

throwOnErrorStatusWidget.description=Si cette case est cochée, aucune sortie n'est envoyée et une erreur est générée si le code d'état n'est pas compris entre 200 et 399
throwOnErrorStatusWidget.label=Activer l'état d'erreur
2 changes: 2 additions & 0 deletions src/main/resources/rest-file-put_ja.properties
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,5 @@ proxy_username_widget.label=ユーザー名
proxy_password_widget.label=パスワード
#proxy_password_widget.description=プロキシ・サーバーから認証が要求される場合のパスワード
outputsDescription=レスポンスの Content-Type が JSON 互換の場合、スクリプトでデータを素早くアクセスするには、'bodyAsObject' output (例: bodyAsObject.user.name または bodyAsObject[0].userName)を使用します。その他の場合は、'bodyAsString' output を使用します。
throwOnErrorStatusWidget.description=チェックされている場合、出力は送信されず、ステータスコードが200から399の間でない場合はエラーが発生します。
throwOnErrorStatusWidget.label=エラーステータスをスローする
2 changes: 2 additions & 0 deletions src/main/resources/rest-get.properties
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,5 @@ proxy_password_widget.label=Password
outputsDescription=If the response Content-Type is Json compatible, use the 'bodyAsObject' output to quickly access your data in a script (e.g: bodyAsObject.user.name, or, in the case of an array, bodyAsObject[0].user.name), use the 'bodyAsString' output otherwise.
socket_timeout_ms_widget.label=Socket timeout
connection_timeout_ms_widget.label=Connection timeout
throwOnErrorStatusWidget.description=If checked, no outputs will be sent, and an error will be thrown if the status code is not between 200 and 399.
throwOnErrorStatusWidget.label=Throw on error status
2 changes: 2 additions & 0 deletions src/main/resources/rest-get_es.properties
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,5 @@ proxy_password_widget.label=Contraseña
proxy_password_widget.description=La contraseña si se requiere autenticación desde el servidor proxy
outputsDescription=Si la respuesta Content-Type es compatible con Json, usa la salida 'bodyAsObject' para acceder rápidamente a los datos en un script (ejemplo: bodyAsObject.user.name o, en el caso de un Array, bodyAsObject[0].userName). Si no es compatible, usa la salida 'bodyAsString'.
urlWidget.example=http://myserver.com/API/myRESTResource?param1=value1&param2=value2
throwOnErrorStatusWidget.description=Si se selecciona, no se enviará ninguna salida y se generará un error si el código de estado no está entre 200 y 399.
throwOnErrorStatusWidget.label=Lanzar en el estado de error
3 changes: 2 additions & 1 deletion src/main/resources/rest-get_fr.properties
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,5 @@ proxy_password_widget.label=Mot de passe
Advanced.pageTitle=Paramètres avancés (optionnel)
Advanced.pageDescription=Saisissez les paramètres avancés du connecteur REST.
outputsDescription=Si le Content-Type (type de contenu) de la réponse est compatible avec JSON, utilisez la sortie 'bodyAsObject' pour accéder rapidement à vos données dans un script (e.g: bodyAsObject.user.name, ou, dans le cas d'un tableau, bodyAsObject[0].user.name), sinon utilisez la sortie 'bodyAsString'.

throwOnErrorStatusWidget.description=Si cette case est cochée, aucune sortie n'est envoyée et une erreur est générée si le code d'état n'est pas compris entre 200 et 399
throwOnErrorStatusWidget.label=Activer l'état d'erreur
Loading

0 comments on commit 1034f8b

Please sign in to comment.