+-- | Serialize the response to String.
+buildResponse :: Bool -- ^ Success
+ -> JSValue -- ^ The arguments
+ -> String -- ^ The serialized form
+buildResponse success args =
+ let ja = [ (strOfKey Success, JSBool success)
+ , (strOfKey Result, args)]
+ jo = toJSObject ja
+ in encodeStrict jo
+
+-- | Check that luxi request contains the required keys and parse it.
+validateCall :: String -> Result LuxiCall
+validateCall s = do
+ arr <- fromJResult "parsing top-level luxi message" $
+ decodeStrict s::Result (JSObject JSValue)
+ let aobj = fromJSObject arr
+ call <- fromObj aobj (strOfKey Method)::Result LuxiReq
+ args <- fromObj aobj (strOfKey Args)
+ return (LuxiCall call args)
+
+-- | Converts Luxi call arguments into a 'LuxiOp' data structure.
+--
+-- This is currently hand-coded until we make it more uniform so that
+-- it can be generated using TH.
+decodeCall :: LuxiCall -> Result LuxiOp
+decodeCall (LuxiCall call args) =
+ case call of
+ ReqQueryJobs -> do
+ (jid, jargs) <- fromJVal args
+ rid <- mapM parseJobId jid
+ let rargs = map fromJSString jargs
+ return $ QueryJobs rid rargs
+ ReqQueryInstances -> do
+ (names, fields, locking) <- fromJVal args
+ return $ QueryInstances names fields locking
+ ReqQueryNodes -> do
+ (names, fields, locking) <- fromJVal args
+ return $ QueryNodes names fields locking
+ ReqQueryGroups -> do
+ (names, fields, locking) <- fromJVal args
+ return $ QueryGroups names fields locking
+ ReqQueryClusterInfo ->
+ return QueryClusterInfo
+ ReqQuery -> do
+ (what, fields, qfilter) <- fromJVal args
+ return $ Query what fields qfilter
+ ReqQueryFields -> do
+ (what, fields) <- fromJVal args
+ fields' <- case fields of
+ JSNull -> return []
+ _ -> fromJVal fields
+ return $ QueryFields what fields'
+ ReqSubmitJob -> do
+ [ops1] <- fromJVal args
+ ops2 <- mapM (fromJResult (luxiReqToRaw call) . J.readJSON) ops1
+ return $ SubmitJob ops2
+ ReqSubmitManyJobs -> do
+ [ops1] <- fromJVal args
+ ops2 <- mapM (fromJResult (luxiReqToRaw call) . J.readJSON) ops1
+ return $ SubmitManyJobs ops2
+ ReqWaitForJobChange -> do
+ (jid, fields, pinfo, pidx, wtmout) <-
+ -- No instance for 5-tuple, code copied from the
+ -- json sources and adapted
+ fromJResult "Parsing WaitForJobChange message" $
+ case args of
+ JSArray [a, b, c, d, e] ->
+ (,,,,) `fmap`
+ J.readJSON a `ap`
+ J.readJSON b `ap`
+ J.readJSON c `ap`
+ J.readJSON d `ap`
+ J.readJSON e
+ _ -> J.Error "Not enough values"
+ rid <- parseJobId jid
+ return $ WaitForJobChange rid fields pinfo pidx wtmout
+ ReqArchiveJob -> do
+ [jid] <- fromJVal args
+ rid <- parseJobId jid
+ return $ ArchiveJob rid
+ ReqAutoArchiveJobs -> do
+ (age, tmout) <- fromJVal args
+ return $ AutoArchiveJobs age tmout
+ ReqQueryExports -> do
+ (nodes, lock) <- fromJVal args
+ return $ QueryExports nodes lock
+ ReqQueryConfigValues -> do
+ [fields] <- fromJVal args
+ return $ QueryConfigValues fields
+ ReqQueryTags -> do
+ (kind, name) <- fromJVal args
+ item <- tagObjectFrom kind name
+ return $ QueryTags item
+ ReqCancelJob -> do
+ [job] <- fromJVal args
+ rid <- parseJobId job
+ return $ CancelJob rid
+ ReqChangeJobPriority -> do
+ (job, priority) <- fromJVal args
+ rid <- parseJobId job
+ return $ ChangeJobPriority rid priority
+ ReqSetDrainFlag -> do
+ [flag] <- fromJVal args
+ return $ SetDrainFlag flag
+ ReqSetWatcherPause -> do
+ [duration] <- fromJVal args
+ return $ SetWatcherPause duration
+