module Ecluse.Core.Server.Pipeline.Origin (
Contribution (..),
fingerprintPiece,
OriginResult (..),
originManifest,
fetchPrivateOrigin,
fetchPublicOrigin,
withPublicMetadataClient,
) where
import Data.Map.Strict qualified as Map
import Katip (Severity (DebugS), logFM, ls)
import Network.HTTP.Client (Manager)
import UnliftIO (withRunInIO)
import UnliftIO.Exception (tryAny)
import Ecluse.Core.Credential (Secret)
import Ecluse.Core.Package (PackageInfo (infoVersions), PackageName, renderPackageName)
import Ecluse.Core.Package.Merge (Provenance)
import Ecluse.Core.Registry.CachedDocument (CachedDoc)
import Ecluse.Core.Registry.Metadata (
ContentDigest,
Manifest,
MetadataClient (fetchFullManifest),
MetadataError (MetadataNameMismatch),
)
import Ecluse.Core.Security (Limits)
import Ecluse.Core.Server.Cache (Source (Source))
import Ecluse.Core.Server.Context (
Handler,
PackumentDeps (..),
ServeRuntime (..),
)
import Ecluse.Core.Server.Metadata (ManifestCaching (Cached, Uncached))
import Ecluse.Core.Server.Pipeline.Diagnostics (logInvalidEntries, logMetadataFailure)
import Ecluse.Core.Telemetry.Metrics qualified as Metric
data Contribution = Contribution
{ Contribution -> Provenance
srcProvenance :: Provenance
, Contribution -> PackageInfo
srcInfo :: PackageInfo
, Contribution -> CachedDoc
srcValue :: CachedDoc
, Contribution -> ContentDigest
srcDigest :: ContentDigest
}
fingerprintPiece :: Contribution -> (Provenance, ContentDigest, [Text])
fingerprintPiece :: Contribution -> (Provenance, ContentDigest, [Text])
fingerprintPiece Contribution
s = (Contribution -> Provenance
srcProvenance Contribution
s, Contribution -> ContentDigest
srcDigest Contribution
s, Map Text PackageDetails -> [Text]
forall k a. Map k a -> [k]
Map.keys (PackageInfo -> Map Text PackageDetails
infoVersions (Contribution -> PackageInfo
srcInfo Contribution
s)))
data OriginResult
=
OriginResolved Manifest
|
OriginNameMismatch
|
OriginUnresolved
|
OriginAbsent
originManifest :: OriginResult -> Maybe Manifest
originManifest :: OriginResult -> Maybe Manifest
originManifest = \case
OriginResolved Manifest
manifest -> Manifest -> Maybe Manifest
forall a. a -> Maybe a
Just Manifest
manifest
OriginResult
OriginNameMismatch -> Maybe Manifest
forall a. Maybe a
Nothing
OriginResult
OriginUnresolved -> Maybe Manifest
forall a. Maybe a
Nothing
OriginResult
OriginAbsent -> Maybe Manifest
forall a. Maybe a
Nothing
originResultOf :: Either SomeException (Either MetadataError Manifest) -> OriginResult
originResultOf :: Either SomeException (Either MetadataError Manifest)
-> OriginResult
originResultOf = \case
Left SomeException
_ -> OriginResult
OriginUnresolved
Right (Left (MetadataNameMismatch Text
_)) -> OriginResult
OriginNameMismatch
Right (Left MetadataError
_) -> OriginResult
OriginUnresolved
Right (Right Manifest
manifest) -> Manifest -> OriginResult
OriginResolved Manifest
manifest
fetchPrivateOrigin :: PackumentDeps -> ServeRuntime -> Maybe Secret -> PackageName -> Handler OriginResult
fetchPrivateOrigin :: PackumentDeps
-> ServeRuntime
-> Maybe Secret
-> PackageName
-> Handler OriginResult
fetchPrivateOrigin PackumentDeps
deps ServeRuntime
rt Maybe Secret
token PackageName
name = case PackumentDeps -> Maybe Text
pdPrivateBaseUrl PackumentDeps
deps of
Maybe Text
Nothing -> OriginResult -> Handler OriginResult
forall a. a -> Handler a
forall (f :: * -> *) a. Applicative f => a -> f a
pure OriginResult
OriginAbsent
Just Text
privateBase -> do
Severity -> LogStr -> Handler ()
forall (m :: * -> *).
(Applicative m, KatipContext m) =>
Severity -> LogStr -> m ()
logFM Severity
DebugS (Text -> LogStr
forall a. StringConv a Text => a -> LogStr
ls (Text
"fetching private origin for " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> PackageName -> Text
renderPackageName PackageName
name))
resolved <-
Handler (Either MetadataError Manifest)
-> Handler (Either SomeException (Either MetadataError Manifest))
forall (m :: * -> *) a.
MonadUnliftIO m =>
m a -> m (Either SomeException a)
tryAny (Handler (Either MetadataError Manifest)
-> Handler (Either SomeException (Either MetadataError Manifest)))
-> Handler (Either MetadataError Manifest)
-> Handler (Either SomeException (Either MetadataError Manifest))
forall a b. (a -> b) -> a -> b
$
ServeRuntime
-> PackumentDeps
-> Upstream
-> ManifestCaching
-> Limits
-> Manager
-> Text
-> Maybe Secret
-> (MetadataClient -> IO (Either MetadataError Manifest))
-> Handler (Either MetadataError Manifest)
forall a.
ServeRuntime
-> PackumentDeps
-> Upstream
-> ManifestCaching
-> Limits
-> Manager
-> Text
-> Maybe Secret
-> (MetadataClient -> IO a)
-> Handler a
withMetadataClient ServeRuntime
rt PackumentDeps
deps Upstream
Metric.Private ManifestCaching
Uncached (PackumentDeps -> Limits
pdLimits PackumentDeps
deps) (ServeRuntime -> Manager
srPrivateManager ServeRuntime
rt) Text
privateBase Maybe Secret
token ((MetadataClient -> IO (Either MetadataError Manifest))
-> Handler (Either MetadataError Manifest))
-> (MetadataClient -> IO (Either MetadataError Manifest))
-> Handler (Either MetadataError Manifest)
forall a b. (a -> b) -> a -> b
$ \MetadataClient
client ->
MetadataClient -> PackageName -> IO (Either MetadataError Manifest)
fetchFullManifest MetadataClient
client PackageName
name
pure (originResultOf resolved)
fetchPublicOrigin :: PackumentDeps -> ServeRuntime -> PackageName -> Handler OriginResult
fetchPublicOrigin :: PackumentDeps
-> ServeRuntime -> PackageName -> Handler OriginResult
fetchPublicOrigin PackumentDeps
deps ServeRuntime
rt PackageName
name = do
Severity -> LogStr -> Handler ()
forall (m :: * -> *).
(Applicative m, KatipContext m) =>
Severity -> LogStr -> m ()
logFM Severity
DebugS (Text -> LogStr
forall a. StringConv a Text => a -> LogStr
ls (Text
"fetching public origin for " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> PackageName -> Text
renderPackageName PackageName
name))
resolved <-
Handler (Either MetadataError Manifest)
-> Handler (Either SomeException (Either MetadataError Manifest))
forall (m :: * -> *) a.
MonadUnliftIO m =>
m a -> m (Either SomeException a)
tryAny (Handler (Either MetadataError Manifest)
-> Handler (Either SomeException (Either MetadataError Manifest)))
-> Handler (Either MetadataError Manifest)
-> Handler (Either SomeException (Either MetadataError Manifest))
forall a b. (a -> b) -> a -> b
$
ServeRuntime
-> PackumentDeps
-> Text
-> (MetadataClient -> IO (Either MetadataError Manifest))
-> Handler (Either MetadataError Manifest)
forall a.
ServeRuntime
-> PackumentDeps -> Text -> (MetadataClient -> IO a) -> Handler a
withPublicMetadataClient ServeRuntime
rt PackumentDeps
deps (PackumentDeps -> Text
pdPublicBaseUrl PackumentDeps
deps) ((MetadataClient -> IO (Either MetadataError Manifest))
-> Handler (Either MetadataError Manifest))
-> (MetadataClient -> IO (Either MetadataError Manifest))
-> Handler (Either MetadataError Manifest)
forall a b. (a -> b) -> a -> b
$ \MetadataClient
client ->
MetadataClient -> PackageName -> IO (Either MetadataError Manifest)
fetchFullManifest MetadataClient
client PackageName
name
pure (originResultOf resolved)
withMetadataClient ::
ServeRuntime ->
PackumentDeps ->
Metric.Upstream ->
ManifestCaching ->
Limits ->
Manager ->
Text ->
Maybe Secret ->
(MetadataClient -> IO a) ->
Handler a
withMetadataClient :: forall a.
ServeRuntime
-> PackumentDeps
-> Upstream
-> ManifestCaching
-> Limits
-> Manager
-> Text
-> Maybe Secret
-> (MetadataClient -> IO a)
-> Handler a
withMetadataClient ServeRuntime
rt PackumentDeps
deps Upstream
upstream ManifestCaching
caching Limits
limits Manager
manager Text
baseUrl Maybe Secret
token MetadataClient -> IO a
k =
((forall a. Handler a -> IO a) -> IO a) -> Handler a
forall b. ((forall a. Handler a -> IO a) -> IO b) -> Handler b
forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO (((forall a. Handler a -> IO a) -> IO a) -> Handler a)
-> ((forall a. Handler a -> IO a) -> IO a) -> Handler a
forall a b. (a -> b) -> a -> b
$ \forall a. Handler a -> IO a
runInIO ->
MetadataClient -> IO a
k (MetadataClient -> IO a) -> MetadataClient -> IO a
forall a b. (a -> b) -> a -> b
$
PackumentDeps
-> TracingPort
-> MetricsPort
-> Upstream
-> ManifestCaching
-> (PackageName -> MetadataError -> IO ())
-> (PackageName -> [InvalidEntry] -> IO ())
-> (PackageName -> IO ())
-> Limits
-> Manager
-> Text
-> Maybe Secret
-> MetadataClient
pdNewMetadataClient
PackumentDeps
deps
(ServeRuntime -> TracingPort
srTracing ServeRuntime
rt)
(ServeRuntime -> MetricsPort
srMetrics ServeRuntime
rt)
Upstream
upstream
ManifestCaching
caching
(\PackageName
nm MetadataError
err -> Handler () -> IO ()
forall a. Handler a -> IO a
runInIO (PackageName -> Text -> MetadataError -> Handler ()
logMetadataFailure PackageName
nm Text
baseUrl MetadataError
err))
(\PackageName
nm [InvalidEntry]
entries -> Handler () -> IO ()
forall a. Handler a -> IO a
runInIO (PackageName -> Text -> [InvalidEntry] -> Handler ()
forall (m :: * -> *).
KatipContext m =>
PackageName -> Text -> [InvalidEntry] -> m ()
logInvalidEntries PackageName
nm Text
baseUrl [InvalidEntry]
entries))
(\PackageName
nm -> Handler () -> IO ()
forall a. Handler a -> IO a
runInIO (Severity -> LogStr -> Handler ()
forall (m :: * -> *).
(Applicative m, KatipContext m) =>
Severity -> LogStr -> m ()
logFM Severity
DebugS (Text -> LogStr
forall a. StringConv a Text => a -> LogStr
ls (Text
"fetching packument from origin for " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> PackageName -> Text
renderPackageName PackageName
nm))))
Limits
limits
Manager
manager
Text
baseUrl
Maybe Secret
token
withPublicMetadataClient :: ServeRuntime -> PackumentDeps -> Text -> (MetadataClient -> IO a) -> Handler a
withPublicMetadataClient :: forall a.
ServeRuntime
-> PackumentDeps -> Text -> (MetadataClient -> IO a) -> Handler a
withPublicMetadataClient ServeRuntime
rt PackumentDeps
deps Text
baseUrl =
ServeRuntime
-> PackumentDeps
-> Upstream
-> ManifestCaching
-> Limits
-> Manager
-> Text
-> Maybe Secret
-> (MetadataClient -> IO a)
-> Handler a
forall a.
ServeRuntime
-> PackumentDeps
-> Upstream
-> ManifestCaching
-> Limits
-> Manager
-> Text
-> Maybe Secret
-> (MetadataClient -> IO a)
-> Handler a
withMetadataClient ServeRuntime
rt PackumentDeps
deps Upstream
Metric.Public (MetadataCache -> Source -> ManifestCaching
Cached (ServeRuntime -> MetadataCache
srMetadataCache ServeRuntime
rt) (Text -> Source
Source Text
baseUrl)) (PackumentDeps -> Limits
pdLimits PackumentDeps
deps) (ServeRuntime -> Manager
srPublicManager ServeRuntime
rt) Text
baseUrl Maybe Secret
forall a. Maybe a
Nothing