这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .circleci/test-server.sh
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ cd $PYTEST_ROOT

RUN_WEBHOOK_TESTS=true

for port in 8080 8081 9876 5592
for port in 8080 8081 9876 5592 5000 5594
do
fail_if_port_busy $port
done
Expand All @@ -205,6 +205,7 @@ fi
export WEBHOOK_FROM_ENV="http://127.0.0.1:5592"
export SCHEDULED_TRIGGERS_WEBHOOK_DOMAIN="http://127.0.0.1:5594"
export HASURA_GRAPHQL_STRINGIFY_NUMERIC_TYPES=true
export REMOTE_SCHEMAS_WEBHOOK_DOMAIN="http://127.0.0.1:5000"

HGE_PIDS=""
WH_PID=""
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ This release contains the [PDV refactor (#4111)](https://github.com/hasura/graph
- server: miscellaneous description changes (#4111)
- server: treat the absence of `backend_only` configuration and `backend_only: false` equally (closing #5059) (#4111)
- server: allow remote relationships joining `type` column with `[type]` input argument as spec allows this coercion (fixes #5133)
- server: add action-like URL templating for event triggers and remote schemas (fixes #2483)
- console: allow user to cascade Postgres dependencies when dropping Postgres objects (close #5109) (#5248)
- console: mark inconsistent remote schemas in the UI (close #5093) (#5181)
- cli: add missing global flags for seeds command (#5565)
Expand Down
4 changes: 3 additions & 1 deletion scripts/dev.sh
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ if [ "$MODE" = "graphql-engine" ]; then
echo_pretty " $ $0 postgres"
echo_pretty ""

RUN_INVOCATION=(cabal new-run --project-file=cabal.project.dev-sh --RTS --
RUN_INVOCATION=(cabal new-run --project-file=cabal.project.dev-sh --RTS --
exe:graphql-engine +RTS -N -T -s -RTS serve
--enable-console --console-assets-dir "$PROJECT_ROOT/console/static/dist"
)
Expand Down Expand Up @@ -371,9 +371,11 @@ elif [ "$MODE" = "test" ]; then
# We'll get an hpc error if these exist; they will be deleted below too:
rm -f graphql-engine-tests.tix graphql-engine.tix graphql-engine-combined.tix

# Various tests take some configuration from the environment; set these up here:
export EVENT_WEBHOOK_HEADER="MyEnvValue"
export WEBHOOK_FROM_ENV="http://127.0.0.1:5592"
export SCHEDULED_TRIGGERS_WEBHOOK_DOMAIN="http://127.0.0.1:5594"
export REMOTE_SCHEMAS_WEBHOOK_DOMAIN="http://127.0.0.1:5000"

# It's better UX to build first (possibly failing) before trying to launch
# PG, but make sure that new-run uses the exact same build plan, else we risk
Expand Down
4 changes: 3 additions & 1 deletion server/src-lib/Hasura/RQL/DDL/EventTrigger.hs
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,9 @@ getWebhookInfoFromConf
-> WebhookConf
-> m WebhookConfInfo
getWebhookInfoFromConf env wc = case wc of
WCValue w -> return $ WebhookConfInfo wc w
WCValue w -> do
resolvedWebhook <- resolveWebhook env w
return $ WebhookConfInfo wc $ unResolvedWebhook resolvedWebhook
WCEnv we -> do
envVal <- getEnv env we
return $ WebhookConfInfo wc envVal
Expand Down
6 changes: 6 additions & 0 deletions server/src-lib/Hasura/RQL/Types/Common.hs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import Hasura.RQL.DDL.Headers ()
import Control.Lens (makeLenses)
import Data.Aeson
import Data.Aeson.Casing
import Data.Bifunctor (bimap)
import Data.Aeson.TH
import Data.URL.Template
import Instances.TH.Lift ()
Expand Down Expand Up @@ -305,6 +306,11 @@ instance FromJSON InputWebhook where
Left e -> fail $ "Parsing URL template failed: " ++ e
Right v -> pure $ InputWebhook v

instance Q.FromCol InputWebhook where
fromCol bs = do
urlTemplate <- parseURLTemplate <$> Q.fromCol bs
bimap (\e -> "Parsing URL template failed: " <> T.pack e) InputWebhook urlTemplate

resolveWebhook :: QErrM m => Env.Environment -> InputWebhook -> m ResolvedWebhook
resolveWebhook env (InputWebhook urlTemplate) = do
let eitherRenderedTemplate = renderURLTemplate env urlTemplate
Expand Down
15 changes: 9 additions & 6 deletions server/src-lib/Hasura/RQL/Types/EventTrigger.hs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import Data.Aeson.TH
import Hasura.Incremental (Cacheable)
import Hasura.Prelude
import Hasura.RQL.DDL.Headers
import Hasura.RQL.Types.Common (NonEmptyText (..))
import Hasura.RQL.Types.Common (NonEmptyText (..), InputWebhook)
import Hasura.SQL.Types
import Language.Haskell.TH.Syntax (Lift)

Expand Down Expand Up @@ -104,18 +104,21 @@ data EventHeaderInfo
instance NFData EventHeaderInfo
$(deriveToJSON (aesonDrop 3 snakeCase){omitNothingFields=True} ''EventHeaderInfo)

data WebhookConf = WCValue T.Text | WCEnv T.Text
data WebhookConf = WCValue InputWebhook | WCEnv T.Text
deriving (Show, Eq, Generic, Lift)
instance NFData WebhookConf
instance Cacheable WebhookConf

instance ToJSON WebhookConf where
toJSON (WCValue w) = String w
toJSON (WCValue w) = toJSON w
toJSON (WCEnv wEnv) = object ["from_env" .= wEnv ]

instance FromJSON WebhookConf where
parseJSON (Object o) = WCEnv <$> o .: "from_env"
parseJSON (String t) = pure $ WCValue t
parseJSON t@(String _) =
case (fromJSON t) of
Error s -> fail s
Success a -> pure $ WCValue a
parseJSON _ = fail "one of string or object must be provided for webhook"

data WebhookConfInfo
Expand All @@ -135,7 +138,7 @@ data CreateEventTriggerQuery
, cetqDelete :: !(Maybe SubscribeOpSpec)
, cetqEnableManual :: !(Maybe Bool)
, cetqRetryConf :: !(Maybe RetryConf)
, cetqWebhook :: !(Maybe T.Text)
, cetqWebhook :: !(Maybe InputWebhook)
, cetqWebhookFromEnv :: !(Maybe T.Text)
, cetqHeaders :: !(Maybe [HeaderConf])
, cetqReplace :: !Bool
Expand Down Expand Up @@ -203,7 +206,7 @@ data EventTriggerConf
= EventTriggerConf
{ etcName :: !TriggerName
, etcDefinition :: !TriggerOpsDef
, etcWebhook :: !(Maybe T.Text)
, etcWebhook :: !(Maybe InputWebhook)
, etcWebhookFromEnv :: !(Maybe T.Text)
, etcRetryConf :: !RetryConf
, etcHeaders :: !(Maybe [HeaderConf])
Expand Down
11 changes: 7 additions & 4 deletions server/src-lib/Hasura/RQL/Types/RemoteSchema.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import qualified Data.Environment as Env

import Hasura.Incremental (Cacheable)
import Hasura.RQL.DDL.Headers (HeaderConf (..))
import Hasura.RQL.Types.Common (NonEmptyText (..))
import Hasura.RQL.Types.Common
import Hasura.RQL.Types.Error
import Hasura.SQL.Types

Expand Down Expand Up @@ -42,7 +42,7 @@ $(J.deriveJSON (J.aesonDrop 2 J.snakeCase) ''RemoteSchemaInfo)

data RemoteSchemaDef
= RemoteSchemaDef
{ _rsdUrl :: !(Maybe N.URI)
{ _rsdUrl :: !(Maybe InputWebhook)
, _rsdUrlFromEnv :: !(Maybe UrlFromEnv)
, _rsdHeaders :: !(Maybe [HeaderConf])
, _rsdForwardClientHeaders :: !Bool
Expand Down Expand Up @@ -94,8 +94,11 @@ validateRemoteSchemaDef
-> m RemoteSchemaInfo
validateRemoteSchemaDef env (RemoteSchemaDef mUrl mUrlEnv hdrC fwdHdrs mTimeout) =
case (mUrl, mUrlEnv) of
(Just url, Nothing) ->
return $ RemoteSchemaInfo url hdrs fwdHdrs timeout
(Just url, Nothing) -> do
resolvedWebhookTxt <- unResolvedWebhook <$> resolveWebhook env url
case N.parseURI $ T.unpack resolvedWebhookTxt of
Nothing -> throw400 InvalidParams $ "not a valid URI: " <> resolvedWebhookTxt
Just uri -> return $ RemoteSchemaInfo uri hdrs fwdHdrs timeout
(Nothing, Just urlEnv) -> do
url <- getUrlFromEnv env urlEnv
return $ RemoteSchemaInfo url hdrs fwdHdrs timeout
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
type: bulk
args:
- type: run_sql
args:
sql: |
create table hge_tests.test_t1(
c1 int,
c2 text
);
- type: track_table
args:
schema: hge_tests
name: test_t1
- type: create_event_trigger
args:
name: t1_all
table:
schema: hge_tests
name: test_t1
insert:
columns: "*"
update:
columns: "*"
delete:
columns: "*"
webhook: "{{WEBHOOK_FROM_ENV}}/trigger"
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
type: bulk
args:
- type: delete_event_trigger
args:
name: t1_all
- type: run_sql
args:
sql: |
drop table hge_tests.test_t1
2 changes: 1 addition & 1 deletion server/tests-py/queries/remote_schemas/tbls_setup.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ args:
name: simple2-graphql
comment: testing
definition:
url: http://localhost:5000/user-graphql
url: "{{REMOTE_SCHEMAS_WEBHOOK_DOMAIN}}/user-graphql"
forward_client_headers: false
37 changes: 37 additions & 0 deletions server/tests-py/test_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,43 @@ def test_basic(self, hge_ctx, evts_webhook):
assert st_code == 200, resp
check_event(hge_ctx, evts_webhook, "t1_all", table, "DELETE", exp_ev_data)

@usefixtures('per_method_tests_db_state')
class TestWebhookTemplateURL(object):

@classmethod
def dir(cls):
return 'queries/event_triggers/webhook_template_url'

def test_basic(self, hge_ctx, evts_webhook):
table = {"schema": "hge_tests", "name": "test_t1"}

init_row = {"c1": 1, "c2": "hello"}
exp_ev_data = {
"old": None,
"new": init_row
}
st_code, resp = insert(hge_ctx, table, init_row)
assert st_code == 200, resp
check_event(hge_ctx, evts_webhook, "t1_all", table, "INSERT", exp_ev_data, webhook_path = '/trigger')

where_exp = {"c1": 1}
set_exp = {"c2": "world"}
exp_ev_data = {
"old": init_row,
"new": {"c1": 1, "c2": "world"}
}
st_code, resp = update(hge_ctx, table, where_exp, set_exp)
assert st_code == 200, resp
check_event(hge_ctx, evts_webhook, "t1_all", table, "UPDATE", exp_ev_data, webhook_path = '/trigger')

exp_ev_data = {
"old": {"c1": 1, "c2": "world"},
"new": None
}
st_code, resp = delete(hge_ctx, table, where_exp)
assert st_code == 200, resp
check_event(hge_ctx, evts_webhook, "t1_all", table, "DELETE", exp_ev_data, webhook_path = '/trigger')

@usefixtures('per_method_tests_db_state')
class TestSessionVariables(object):

Expand Down