summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorstuebinm2022-02-16 19:38:08 +0100
committerstuebinm2022-02-16 19:38:08 +0100
commitb3c3b5d727f2c8548ab72ff07a0f8c6b9844bfac (patch)
treed59b7c7ab9fa9f90fd08066b473d1a666ee7254b
parent3b144c97636620a6fbd3807a8847b5751f86a52d (diff)
server: post map updates to exneuland's API
-rw-r--r--config.toml1
-rw-r--r--package.yaml4
-rw-r--r--server/Main.hs55
-rw-r--r--server/Server.hs29
-rw-r--r--walint.cabal2
5 files changed, 71 insertions, 20 deletions
diff --git a/config.toml b/config.toml
index 1f0f349..cda774b 100644
--- a/config.toml
+++ b/config.toml
@@ -7,6 +7,7 @@ tmpdir = "/tmp"
# linting interval in seconds
interval = 30
+exneuland = "http://localhost:4000"
[[org]]
slug = "divoc"
diff --git a/package.yaml b/package.yaml
index 3bcac30..ac13e9a 100644
--- a/package.yaml
+++ b/package.yaml
@@ -66,11 +66,13 @@ executables:
- warp
- wai
- wai-extra
+ - lucid
- servant
- servant-server
- - lucid
+ - servant-client
- servant-lucid
- http-types
+ - http-client
- process
- extra
- microlens-platform
diff --git a/server/Main.hs b/server/Main.hs
index 660b69e..8ea59d6 100644
--- a/server/Main.hs
+++ b/server/Main.hs
@@ -10,7 +10,14 @@
-- | simple server offering linting "as a service"
module Main where
-import Universum
+import Universum (Container (length), IO,
+ MVar, Monad ((>>=)),
+ Num ((*)), Proxy (Proxy),
+ Text, atomically, forM_,
+ forever, map, newMVar,
+ print, putTextLn,
+ readMVar, view, void,
+ ($), (.))
import Control.Concurrent (threadDelay)
import Control.Concurrent.Async (async, link, waitEither_)
@@ -22,6 +29,8 @@ import Handlers (AdminOverview (AdminOverv
MapService (MapService),
stateImpl, statusImpl)
import HtmlOrphans ()
+import Network.HTTP.Client (defaultManagerSettings,
+ newManager)
import Network.Wai.Handler.Warp (defaultSettings,
runSettings, setPort)
import Network.Wai.Middleware.Gzip (def)
@@ -29,32 +38,42 @@ import Network.Wai.Middleware.RequestLogger (OutputFormat (..),
RequestLoggerSettings (..),
mkRequestLogger)
import Servant (Application, Capture,
- Get, JSON, Raw, Server,
- serve, type (:<|>) (..),
+ EmptyAPI, Get, JSON,
+ PlainText, Post, Raw,
+ ReqBody, Server, serve,
+ type (:<|>) (..),
type (:>))
import Servant.HTML.Lucid (HTML)
import Servant.Server.StaticFiles (serveDirectoryWebApp)
import Server (JobStatus, Org (..),
ServerState, Sha1,
- emptyState, interval,
- loadConfig, orgs, port,
- unState, verbose)
+ emptyState, exneuland,
+ interval, loadConfig,
+ orgs, port, unState,
+ verbose)
import Worker (Job (Job), linterThread)
+import Servant.Client (BaseUrl (BaseUrl),
+ ClientM, Scheme (Http),
+ client, mkClientEnv,
+ runClientM)
--- | that thing we need to replace the hub
-type MapServiceAPI = "api" :> "maps" :> "list" :> Get '[JSON] MapService
+type family PolyEndpoint method format payload where
+ PolyEndpoint Get format payload = Get format payload
+ PolyEndpoint Post format payload = ReqBody format payload :> Post '[PlainText] Text
+
+
+type MapServiceAPI method =
+ "api" :> "maps" :> "list" :> PolyEndpoint method '[JSON] MapService
-- | abstract api
type API format =
- -- "submit" :> ReqBody '[JSON] RemoteRef :> Post '[format] UUID
"status" :> Capture "org" Text :> Capture "jobid" Sha1 :> Get '[format] JobStatus
- -- :<|> "relint" :> Capture "jobid" UUID :> Get '[format] NoContent
:<|> "admin" :> "overview" :> Get '[format] AdminOverview
-- | actual set of routes: api for json & html + static pages from disk
type Routes = "api" :> API JSON
- :<|> MapServiceAPI
+ :<|> MapServiceAPI Get
:<|> API HTML -- websites mirror the API exactly
:<|> Raw
@@ -73,6 +92,9 @@ server state = jsonAPI @JSON state
app :: MVar ServerState -> Application
app = serve (Proxy @Routes) . server
+postNewMaps :: MapService -> ClientM Text
+postNewMaps = client (Proxy @(MapServiceAPI Post))
+
main :: IO ()
main = do
config <- loadConfig "./config.toml"
@@ -96,10 +118,21 @@ main = do
-- microseconds for some reason
threadDelay (view interval config * 1000000)
+ -- TODO: what about tls / https?
+ manager' <- newManager defaultManagerSettings
+ updater <- async $ forever $ do
+ done <- readMVar state
+ res <- runClientM
+ (postNewMaps (MapService done))
+ (mkClientEnv manager' (view exneuland config))
+ print res
+ threadDelay (view interval config * 1000000)
+
-- spawns threads for each job in the queue
linter <- async $ void $ linterThread config queue state
link linter
link poker
+ link updater
let warpsettings =
setPort (view port config)
diff --git a/server/Server.hs b/server/Server.hs
index bcb96a0..ef01b88 100644
--- a/server/Server.hs
+++ b/server/Server.hs
@@ -19,7 +19,7 @@
module Server ( loadConfig
, Org(..)
, Sha1
- , Config, tmpdir, port, verbose, orgs, interval
+ , Config, tmpdir, port, verbose, orgs, interval, exneuland
, RemoteRef(..)
, ServerState, emptyState, unState
, JobStatus(..)
@@ -29,6 +29,7 @@ module Server ( loadConfig
import Universum
import CheckDir (DirResult)
+import Control.Arrow ((>>>))
import Control.Concurrent (modifyMVar_, withMVar)
import Crypto.Hash.SHA1 (hash)
import Data.Aeson (FromJSON, ToJSON, ToJSONKey (..),
@@ -40,9 +41,14 @@ import qualified Data.Map as M
import Lens.Micro.Platform (at, ix, makeLenses, traverseOf)
import LintConfig (LintConfig')
import Servant (FromHttpApiData)
-import Toml (TomlCodec, prettyTomlDecodeErrors,
- (.=))
+import Servant.Client (BaseUrl,
+ parseBaseUrl)
+import Toml (BiMap (BiMap), TomlBiMap,
+ TomlBiMapError (ArbitraryError),
+ TomlCodec,
+ prettyTomlDecodeErrors, (.=))
import qualified Toml as T
+import Data.Either.Extra (mapLeft)
-- | a reference in a remote git repository
data RemoteRef = RemoteRef
@@ -103,13 +109,14 @@ instance ToJSONKey (Org True) where
-- | the server's configuration
data Config (loaded :: Bool) = Config
- { _tmpdir :: FilePath
+ { _tmpdir :: FilePath
-- ^ dir to clone git things in
- , _port :: Int
- , _verbose :: Bool
- , _interval :: Int
+ , _port :: Int
+ , _verbose :: Bool
+ , _interval :: Int
-- ^ port to bind to
- , _orgs :: [Org loaded]
+ , _exneuland :: BaseUrl
+ , _orgs :: [Org loaded]
} deriving Generic
makeLenses ''Config
@@ -130,6 +137,11 @@ orgCodec = Org
<*> T.text "url" .= orgUrl
<*> T.text "webdir" .= orgWebdir
+-- why exactly does everything in tomland need to be invertable
+urlBimap :: TomlBiMap BaseUrl String
+urlBimap = BiMap
+ (Right . show)
+ (mapLeft (ArbitraryError . show) . parseBaseUrl)
configCodec :: TomlCodec (Config False)
configCodec = Config
@@ -137,6 +149,7 @@ configCodec = Config
<*> T.int "port" .= _port
<*> T.bool "verbose" .= _verbose
<*> T.int "interval" .= _interval
+ <*> T.match (urlBimap >>> T._String) "exneuland" .= _exneuland
<*> T.list orgCodec "org" .= _orgs
-- | a job status (of a specific uuid)
diff --git a/walint.cabal b/walint.cabal
index e721b0d..c2a19a1 100644
--- a/walint.cabal
+++ b/walint.cabal
@@ -105,12 +105,14 @@ executable walint-server
, extra
, filepath
, fmt
+ , http-client
, http-types
, lucid
, microlens-platform
, mtl
, process
, servant
+ , servant-client
, servant-lucid
, servant-server
, stm