Skip to content

Commit

Permalink
fix(oracle): discard nested tokens when checking table
Browse files Browse the repository at this point in the history
  • Loading branch information
paulozulato committed Jul 19, 2023
1 parent 57e39f4 commit e76ba76
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 3 deletions.
20 changes: 20 additions & 0 deletions apps/emqx_bridge_oracle/test/emqx_bridge_oracle_SUITE.erl
Expand Up @@ -162,6 +162,9 @@ delete_all_bridges() ->
sql_insert_template_for_bridge() ->
"INSERT INTO mqtt_test(topic, msgid, payload, retain) VALUES (${topic}, ${id}, ${payload}, ${retain})".

sql_insert_template_with_nested_token_for_bridge() ->
"INSERT INTO mqtt_test(topic, msgid, payload, retain) VALUES (${topic}, ${id}, ${payload.msg}, ${retain})".

sql_create_table() ->
"CREATE TABLE mqtt_test (topic VARCHAR2(255), msgid VARCHAR2(64), payload NCLOB, retain NUMBER(1))".

Expand Down Expand Up @@ -533,6 +536,23 @@ t_start_stop(Config) ->
),
ok.

t_probe_with_nested_tokens(Config) ->
ResourceId = resource_id(Config),
reset_table(Config),
?assertMatch(
{ok, _},
create_bridge(Config, #{
<<"sql">> => sql_insert_template_with_nested_token_for_bridge()
})
),
%% Since the connection process is async, we give it some time to
%% stabilize and avoid flakiness.
?retry(
_Sleep = 1_000,
_Attempts = 20,
?assertEqual({ok, connected}, emqx_resource_manager:health_check(ResourceId))
).

t_on_get_status(Config) ->
ProxyPort = ?config(proxy_port, Config),
ProxyHost = ?config(proxy_host, Config),
Expand Down
2 changes: 1 addition & 1 deletion apps/emqx_oracle/src/emqx_oracle.app.src
@@ -1,6 +1,6 @@
{application, emqx_oracle, [
{description, "EMQX Enterprise Oracle Database Connector"},
{vsn, "0.1.3"},
{vsn, "0.1.4"},
{registered, []},
{applications, [
kernel,
Expand Down
20 changes: 18 additions & 2 deletions apps/emqx_oracle/src/emqx_oracle.erl
Expand Up @@ -9,6 +9,10 @@
-include_lib("emqx/include/logger.hrl").
-include_lib("snabbkaffe/include/snabbkaffe.hrl").

-define(UNHEALTHY_TARGET_MSG,
"Oracle table is invalid. Please check if the table exists in Oracle Database."
).

%%====================================================================
%% Exports
%%====================================================================
Expand Down Expand Up @@ -239,7 +243,7 @@ on_get_status(_InstId, #{pool_name := Pool} = State) ->
{connected, NState};
{error, {undefined_table, NState}} ->
%% return new state indicating that we are connected but the target table is not created
{disconnected, NState, unhealthy_target};
{disconnected, NState, {unhealthy_target, ?UNHEALTHY_TARGET_MSG}};
{error, _Reason} ->
%% do not log error, it is logged in prepare_sql_to_conn
connecting
Expand Down Expand Up @@ -408,7 +412,19 @@ prepare_sql_to_conn(Conn, [{Key, SQL} | PrepareList], TokensMap, Statements) whe
Error
end.

check_if_table_exists(Conn, SQL, Tokens) ->
check_if_table_exists(Conn, SQL, Tokens0) ->
% Discard nested tokens for checking if table exist. As payload here is defined as
% a single string, it would fail if Token is, for instance, ${payload.msg}, causing
% bridge probe to fail.
Tokens = lists:map(
fun
({var, [Token | _DiscardedDeepTokens]}) ->
{var, [Token]};
(Token) ->
Token
end,
Tokens0
),
{Event, _Headers} = emqx_rule_events:eventmsg_publish(
emqx_message:make(<<"t/opic">>, "test query")
),
Expand Down
1 change: 1 addition & 0 deletions changes/ee/fix-11307.en.md
@@ -0,0 +1 @@
Fixed check for table existence to return a more friendly message in the Oracle bridge.

0 comments on commit e76ba76

Please sign in to comment.