2022-11-17 15:55:05 +03:00
|
|
|
{-# LANGUAGE UndecidableInstances #-}
|
|
|
|
|
|
|
|
module Main (main) where
|
|
|
|
|
2023-03-02 17:44:25 +03:00
|
|
|
import Constants qualified
|
2022-11-17 15:55:05 +03:00
|
|
|
import Control.Concurrent.MVar
|
2023-03-27 13:25:55 +03:00
|
|
|
import Control.Monad.Trans.Managed (lowerManagedT)
|
2022-11-17 15:55:05 +03:00
|
|
|
import Control.Natural ((:~>) (..))
|
|
|
|
import Data.Aeson qualified as A
|
|
|
|
import Data.ByteString.Lazy.Char8 qualified as BL
|
|
|
|
import Data.ByteString.Lazy.UTF8 qualified as LBS
|
|
|
|
import Data.Environment qualified as Env
|
2023-02-24 21:09:36 +03:00
|
|
|
import Data.Text qualified as T
|
2022-11-17 15:55:05 +03:00
|
|
|
import Data.Time.Clock (getCurrentTime)
|
|
|
|
import Data.URL.Template
|
|
|
|
import Database.PG.Query qualified as PG
|
|
|
|
import Hasura.App
|
2023-03-23 18:51:18 +03:00
|
|
|
( AppM,
|
|
|
|
BasicConnectionInfo (..),
|
2023-03-23 00:40:26 +03:00
|
|
|
initMetadataConnectionInfo,
|
2023-03-27 13:25:55 +03:00
|
|
|
initialiseAppEnv,
|
2022-11-17 15:55:05 +03:00
|
|
|
mkMSSQLSourceResolver,
|
|
|
|
mkPgSourceResolver,
|
2023-03-23 18:51:18 +03:00
|
|
|
runAppM,
|
2022-11-17 15:55:05 +03:00
|
|
|
)
|
|
|
|
import Hasura.Backends.Postgres.Connection.Settings
|
|
|
|
import Hasura.Backends.Postgres.Execute.Types
|
2023-02-03 04:03:23 +03:00
|
|
|
import Hasura.Base.Error
|
2022-11-17 15:55:05 +03:00
|
|
|
import Hasura.GraphQL.Schema.Options qualified as Options
|
|
|
|
import Hasura.Logging
|
|
|
|
import Hasura.Prelude
|
|
|
|
import Hasura.RQL.DDL.Schema.Cache
|
|
|
|
import Hasura.RQL.DDL.Schema.Cache.Common
|
|
|
|
import Hasura.RQL.Types.Common
|
|
|
|
import Hasura.RQL.Types.Metadata (emptyMetadataDefaults)
|
|
|
|
import Hasura.RQL.Types.ResizePool
|
2023-03-28 16:26:08 +03:00
|
|
|
import Hasura.RQL.Types.SchemaCache
|
2022-11-17 15:55:05 +03:00
|
|
|
import Hasura.RQL.Types.SchemaCache.Build
|
|
|
|
import Hasura.Server.Init
|
2023-01-23 16:35:48 +03:00
|
|
|
import Hasura.Server.Init.FeatureFlag as FF
|
2023-02-24 21:09:36 +03:00
|
|
|
import Hasura.Server.Metrics (ServerMetricsSpec, createServerMetrics)
|
2022-11-17 15:55:05 +03:00
|
|
|
import Hasura.Server.Migrate
|
2023-02-24 21:09:36 +03:00
|
|
|
import Hasura.Server.Prometheus (makeDummyPrometheusMetrics)
|
2022-11-17 15:55:05 +03:00
|
|
|
import Hasura.Server.Types
|
2023-02-24 21:09:36 +03:00
|
|
|
import Hasura.Tracing (sampleAlways)
|
2022-11-17 15:55:05 +03:00
|
|
|
import Network.HTTP.Client qualified as HTTP
|
|
|
|
import Network.HTTP.Client.TLS qualified as HTTP
|
|
|
|
import System.Environment (getEnvironment)
|
|
|
|
import System.Exit (exitFailure)
|
2023-02-24 21:09:36 +03:00
|
|
|
import System.Metrics qualified as EKG
|
2023-02-20 20:41:55 +03:00
|
|
|
import Test.Hasura.EventTriggerCleanupSuite qualified as EventTriggerCleanupSuite
|
|
|
|
import Test.Hasura.Server.MigrateSuite qualified as MigrateSuite
|
|
|
|
import Test.Hasura.StreamingSubscriptionSuite qualified as StreamingSubscriptionSuite
|
2022-11-17 15:55:05 +03:00
|
|
|
import Test.Hspec
|
|
|
|
|
2023-03-30 17:30:19 +03:00
|
|
|
{-# ANN main ("HLINT: ignore avoid getEnvironment" :: String) #-}
|
2022-11-17 15:55:05 +03:00
|
|
|
main :: IO ()
|
|
|
|
main = do
|
|
|
|
env <- getEnvironment
|
|
|
|
let envMap = Env.mkEnvironment env
|
|
|
|
|
|
|
|
pgUrlText <- flip onLeft printErrExit $
|
|
|
|
runWithEnv env $ do
|
|
|
|
let envVar = _envVar databaseUrlOption
|
|
|
|
maybeV <- considerEnv envVar
|
|
|
|
onNothing maybeV $
|
|
|
|
throwError $
|
|
|
|
"Expected: " <> envVar
|
|
|
|
|
|
|
|
let pgConnInfo = PG.ConnInfo 1 $ PG.CDDatabaseURI $ txtToBs pgUrlText
|
|
|
|
urlConf = UrlValue $ InputWebhook $ mkPlainURLTemplate pgUrlText
|
|
|
|
sourceConnInfo =
|
|
|
|
PostgresSourceConnInfo urlConf (Just setPostgresPoolSettings) True PG.ReadCommitted Nothing
|
2023-01-25 10:12:53 +03:00
|
|
|
sourceConfig = PostgresConnConfiguration sourceConnInfo Nothing defaultPostgresExtensionsSchema Nothing mempty
|
2023-02-24 21:09:36 +03:00
|
|
|
rci =
|
|
|
|
PostgresConnInfo
|
|
|
|
{ _pciDatabaseConn = Nothing,
|
|
|
|
_pciRetries = Nothing
|
|
|
|
}
|
|
|
|
serveOptions = Constants.serveOptions
|
|
|
|
metadataDbUrl = Just (T.unpack pgUrlText)
|
2022-11-17 15:55:05 +03:00
|
|
|
|
|
|
|
pgPool <- PG.initPGPool pgConnInfo PG.defaultConnParams {PG.cpConns = 1} print
|
|
|
|
let pgContext = mkPGExecCtx PG.Serializable pgPool NeverResizePool
|
|
|
|
|
|
|
|
logger :: Logger Hasura = Logger $ \l -> do
|
|
|
|
let (logLevel, logType :: EngineLogType Hasura, logDetail) = toEngineLog l
|
|
|
|
t <- liftIO $ getFormattedTime Nothing
|
|
|
|
liftIO $ putStrLn $ LBS.toString $ A.encode $ EngineLog t logLevel logType logDetail
|
|
|
|
|
|
|
|
setupCacheRef = do
|
|
|
|
httpManager <- HTTP.newManager HTTP.tlsManagerSettings
|
2023-03-23 00:40:26 +03:00
|
|
|
metadataConnectionInfo <- initMetadataConnectionInfo envMap metadataDbUrl rci
|
|
|
|
let globalCtx = BasicConnectionInfo metadataConnectionInfo Nothing
|
2023-02-24 21:09:36 +03:00
|
|
|
(_, serverMetrics) <-
|
|
|
|
liftIO $ do
|
|
|
|
store <- EKG.newStore @TestMetricsSpec
|
|
|
|
serverMetrics <-
|
|
|
|
liftIO $ createServerMetrics $ EKG.subset ServerSubset store
|
|
|
|
pure (EKG.subset EKG.emptyOf store, serverMetrics)
|
|
|
|
prometheusMetrics <- makeDummyPrometheusMetrics
|
2022-11-17 15:55:05 +03:00
|
|
|
let sqlGenCtx =
|
|
|
|
SQLGenCtx
|
|
|
|
Options.Don'tStringifyNumbers
|
|
|
|
Options.Don'tDangerouslyCollapseBooleans
|
|
|
|
Options.Don'tOptimizePermissionFilters
|
|
|
|
Options.EnableBigQueryStringNumericInput
|
|
|
|
maintenanceMode = MaintenanceModeDisabled
|
|
|
|
readOnlyMode = ReadOnlyModeDisabled
|
|
|
|
serverConfigCtx =
|
|
|
|
ServerConfigCtx
|
|
|
|
Options.InferFunctionPermissions
|
|
|
|
Options.DisableRemoteSchemaPermissions
|
|
|
|
sqlGenCtx
|
|
|
|
maintenanceMode
|
|
|
|
mempty
|
|
|
|
EventingEnabled
|
|
|
|
readOnlyMode
|
2023-01-30 07:59:30 +03:00
|
|
|
(_default defaultNamingConventionOption)
|
2022-11-17 15:55:05 +03:00
|
|
|
emptyMetadataDefaults
|
2023-03-22 13:46:54 +03:00
|
|
|
(CheckFeatureFlag $ FF.checkFeatureFlag mempty)
|
2023-03-15 11:14:20 +03:00
|
|
|
ApolloFederationDisabled
|
Remove `HasServerConfigCtx` from the schema cache build.
## Description
This PR is a incremental step towards achieving the goal of #8344. It is a less ambitious version of #8484.
This PR removes all references to `HasServerConfigCtx` from the cache build and removes `ServerConfigCtx` from `CacheBuildParams`, making `ServerConfigCtx` an argument being passed around manually instead. This has several benefits: by making it an arrow argument, we now properly integrate the fields that change over time in the dependency framework, as they should be, and we can clean up some of the top-level app code.
## Implementation
In practice, this PR introduces a `HasServerConfigCtx` instance for `CacheRWT`, the monad we use to build the cache, so we can retrieve the `ServerConfigCtx` in the implementation of `CacheRWM`. This contributes to reducing the amount of `HasServerConfigCtx` in the code: we can remove `SchemaUpdateT` altogether, and we can remove the `HasServerConfigCtx` instance of `Handler`. This makes `HasServerConfigCtx` almost **an implementation detail of the Metadata API**.
This first step is enough to achieve the goal of #8344: we can now build the schema cache in the app monad, since we no longer rely on `HasServerConfigCtx` to build it.
## Drawbacks
This PR does not attempt to remove the use of `ServerConfigCtx` itself in the schema cache build: doing so would make this PR much much bigger. Ideally, to avoid having all the static fields given as arrow-ish arguments to the cache, we could depend on `HasAppEnv` in the cache build, and use `AppContext` as an arrow argument. But making the cache build depend on the full `AppEnv` and `AppContext` creates a lot of circular imports; and since removing `ServerConfigCtx` itself isn't required to achieve #8344, this PR keeps it wholesale and defers cleaning it to a future PR.
A negative consequence of this is that we need an `Eq` instance on `ServerConfigCtx`, and that instance is inelegant.
## Future work
There are several further steps we can take in parallel after this is merged. First, again, we can make a new version of #8344, removing `CacheBuild`, FINALLY. As for `ServerConfigCtx`, we can split it / rename it to make ad-hoc structures. If it turns out that `ServerConfigCtx` is only ever used for the schema cache build, we could split it between `CacheBuildEnv` and `CacheBuildContext`, which will be subsets of `AppEnv` and `AppContext`, avoiding import loops.
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/8509
GitOrigin-RevId: 01b37cc3fd3490d6b117701e22fc4ac88b62b6b5
2023-03-27 20:42:37 +03:00
|
|
|
cacheBuildParams = CacheBuildParams httpManager (mkPgSourceResolver print) mkMSSQLSourceResolver
|
2022-11-17 15:55:05 +03:00
|
|
|
|
2023-03-27 13:25:55 +03:00
|
|
|
(_appInit, appEnv) <-
|
|
|
|
lowerManagedT $
|
|
|
|
initialiseAppEnv
|
2023-02-24 21:09:36 +03:00
|
|
|
envMap
|
|
|
|
globalCtx
|
|
|
|
serveOptions
|
|
|
|
Nothing
|
|
|
|
serverMetrics
|
|
|
|
prometheusMetrics
|
|
|
|
sampleAlways
|
|
|
|
|
2023-03-23 18:51:18 +03:00
|
|
|
let run :: ExceptT QErr AppM a -> IO a
|
2022-11-17 15:55:05 +03:00
|
|
|
run =
|
2023-02-03 04:03:23 +03:00
|
|
|
runExceptT
|
2023-03-23 18:51:18 +03:00
|
|
|
>>> runAppM appEnv
|
Clean `AppEnv` and `AppContext` passing, remove `RunT`, reduce `ServerConfigCtx` uses
## Description
This PR does several different things that happen to overlap; the most important being:
- it removes `RunT`: it was redundant in places where we already had `Handler`, and only used in one other place, `SchemaUpdate`, for which a local `SchemaUpdateT` is more than enough;
- it reduces the number of places where we create a `ServerConfigCtx`, since now `HasServerConfigCtx` can be implemented directly by `SchemaUpdateT` and `Handler` based on the full `AppContext`;
- it drastically reduces the number of arguments we pass around in the app init code, by introducing `HasAppEnv`;
- it simplifies `HandlerCtx` to reduce duplication
In doing so, this changes paves the way towards removing `ServerConfigCtx`, since there are only very few places where we construct it: we can now introduce smaller classes than `HasServerConfigCtx`, that expose only a relevant subset of fields, and implement them where we now implement `HasServerConfigCtx`.
This PR is loosely based on ideas in #8337, that are no longer applicable due to the changes introduced in #8159. A challenge of this PR was the postgres tests, which were running in `PGMetadataStorageAppT CacheBuild` :scream_cat:
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/8392
GitOrigin-RevId: b90c1359066d20dbea329c87762ccdd1217b4d69
2023-03-21 13:44:21 +03:00
|
|
|
>>> flip onLeftM printErrJExit
|
2022-11-17 15:55:05 +03:00
|
|
|
|
2023-03-23 00:40:26 +03:00
|
|
|
-- why are we building the schema cache here? it's already built in initialiseContext
|
2022-11-17 15:55:05 +03:00
|
|
|
(metadata, schemaCache) <- run do
|
2023-03-28 16:26:08 +03:00
|
|
|
metadataWithVersion <-
|
2022-11-17 15:55:05 +03:00
|
|
|
snd
|
2023-01-25 10:12:53 +03:00
|
|
|
<$> (liftEitherM . runExceptT . _pecRunTx pgContext (PGExecCtxInfo (Tx PG.ReadWrite Nothing) InternalRawQuery))
|
2022-11-17 15:55:05 +03:00
|
|
|
(migrateCatalog (Just sourceConfig) defaultPostgresExtensionsSchema maintenanceMode =<< liftIO getCurrentTime)
|
2023-03-28 16:26:08 +03:00
|
|
|
schemaCache <- runCacheBuild cacheBuildParams $ buildRebuildableSchemaCache logger envMap metadataWithVersion serverConfigCtx
|
|
|
|
pure (_mwrvMetadata metadataWithVersion, schemaCache)
|
2022-11-17 15:55:05 +03:00
|
|
|
|
|
|
|
cacheRef <- newMVar schemaCache
|
Clean `AppEnv` and `AppContext` passing, remove `RunT`, reduce `ServerConfigCtx` uses
## Description
This PR does several different things that happen to overlap; the most important being:
- it removes `RunT`: it was redundant in places where we already had `Handler`, and only used in one other place, `SchemaUpdate`, for which a local `SchemaUpdateT` is more than enough;
- it reduces the number of places where we create a `ServerConfigCtx`, since now `HasServerConfigCtx` can be implemented directly by `SchemaUpdateT` and `Handler` based on the full `AppContext`;
- it drastically reduces the number of arguments we pass around in the app init code, by introducing `HasAppEnv`;
- it simplifies `HandlerCtx` to reduce duplication
In doing so, this changes paves the way towards removing `ServerConfigCtx`, since there are only very few places where we construct it: we can now introduce smaller classes than `HasServerConfigCtx`, that expose only a relevant subset of fields, and implement them where we now implement `HasServerConfigCtx`.
This PR is loosely based on ideas in #8337, that are no longer applicable due to the changes introduced in #8159. A challenge of this PR was the postgres tests, which were running in `PGMetadataStorageAppT CacheBuild` :scream_cat:
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/8392
GitOrigin-RevId: b90c1359066d20dbea329c87762ccdd1217b4d69
2023-03-21 13:44:21 +03:00
|
|
|
pure $ NT (run . flip MigrateSuite.runCacheRefT (serverConfigCtx, cacheRef) . fmap fst . runMetadataT metadata emptyMetadataDefaults)
|
2022-11-17 15:55:05 +03:00
|
|
|
|
|
|
|
streamingSubscriptionSuite <- StreamingSubscriptionSuite.buildStreamingSubscriptionSuite
|
|
|
|
eventTriggerLogCleanupSuite <- EventTriggerCleanupSuite.buildEventTriggerCleanupSuite
|
|
|
|
|
|
|
|
hspec do
|
|
|
|
describe "Migrate suite" $
|
|
|
|
beforeAll setupCacheRef $
|
|
|
|
describe "Hasura.Server.Migrate" $
|
|
|
|
MigrateSuite.suite sourceConfig pgContext pgConnInfo
|
|
|
|
describe "Streaming subscription suite" $ streamingSubscriptionSuite
|
|
|
|
describe "Event trigger log cleanup suite" $ eventTriggerLogCleanupSuite
|
|
|
|
|
|
|
|
printErrExit :: String -> IO a
|
|
|
|
printErrExit = (*> exitFailure) . putStrLn
|
|
|
|
|
|
|
|
printErrJExit :: (A.ToJSON a) => a -> IO b
|
|
|
|
printErrJExit = (*> exitFailure) . BL.putStrLn . A.encode
|
2023-02-24 21:09:36 +03:00
|
|
|
|
|
|
|
-- | Used only for 'runApp' above.
|
|
|
|
data TestMetricsSpec name metricType tags
|
|
|
|
= ServerSubset (ServerMetricsSpec name metricType tags)
|