{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE FlexibleContexts #-}
module Managed.Connectors.HTTPConnector.Internal
( ManagedAPI
, mkServer
, mkApp
) where
import Control.Exception (displayException, try)
import Control.Monad.IO.Class (liftIO)
import Data.Aeson (encode)
import Data.Managed hiding (JSON)
import Data.Managed.Instances.JSON
import Managed.Agent
import Managed.Exception
import Network.Wai
import Servant
type ManagedAPI
= "probes" :> (Get '[ JSON] [ProbeID] :<|> Capture "probe" ProbeID :> Get '[ JSON] ProbeDescription :<|> Capture "probe" ProbeID :> "invoke" :> ReqBody '[ JSON] [String] :> Post '[ JSON] String)
mkServer :: Agent SR -> Server ManagedAPI
mkServer agent =
handleList agent :<|> handleDescribe agent :<|> handleInvoke agent
handleList :: Agent SR -> Handler [ProbeID]
handleList = return . ids
handleDescribe :: Agent SR -> [Char] -> Handler ProbeDescription
handleDescribe a p = safely (return $ describeEither a p)
handleInvoke :: Agent SR -> ProbeID -> [String] -> Handler String
handleInvoke agent probe args = safely (invoke agent probe args)
errCode :: AgentException -> ServerError
errCode (ProbeRuntimeException _) = err500
errCode _ = err400
mkApp :: Agent SR -> Application
mkApp agent = serve (Proxy @ManagedAPI) (mkServer agent)
safely :: IO (Either AgentException b) -> Handler b
safely action = do
x <- liftIO action
case x of
Left e ->
throwError $
(errCode e) {errBody = Data.Aeson.encode . displayException $ e}
Right val -> return val