1 -- SPDX-FileCopyrightText: 2022 Frank Doepper
3 -- SPDX-License-Identifier: GPL-3.0-only
5 {-# LANGUAGE OverloadedStrings #-}
7 -- generic AMQP rpc client
8 import Control.Concurrent
9 import qualified Control.Exception as X
11 import qualified Data.ByteString.Char8 as BS
12 import qualified Data.ByteString.Lazy.Char8 as BL
13 import qualified Data.Text as T
15 import Data.Time.Clock.POSIX
16 import Data.Version (showVersion)
18 import Network.AMQP.Utils.Connection
19 import Network.AMQP.Utils.Helpers
20 import Network.AMQP.Utils.Options
21 import Paths_amqp_utils (version)
22 import System.Environment
25 import qualified System.File.OsPath as FOS
26 import qualified System.OsPath as OS
32 args <- getArgs >>= parseargs 'p'
34 (printparam "rpc_timeout" [show (rpc_timeout args), "s"])
35 (error $ "invalid rpc_timeout")
36 printparam "client version" ["amqp-utils", showVersion version]
37 printparam "routing key" $ rKey args
38 (conn, chan) <- connect args
39 addChannelExceptionHandler chan (X.throwTo tid)
40 (q, _, _) <- declareQueue chan newQueue {queueExclusive = True}
41 if (currentExchange args /= "")
43 printparam "exchange" $ currentExchange args
44 bindQueue chan q (T.pack $ currentExchange args) q
46 let inputFile' = firstInputFile (inputFiles args)
47 printparam "input file" $ inputFile'
51 else OS.encodeUtf (BS.unpack inputFile') >>= FOS.readFile
52 printparam "output file" $ outputFile args
54 if outputFile args == "-"
56 else openBinaryFile (outputFile args) WriteMode
57 ctag <- consumeMsgs chan q NoAck (rpcClientCallback h tid args)
58 printparam "consumer tag" ctag
59 now <- getCurrentTime >>= return . floor . utcTimeToPOSIXSeconds
60 hr "publishing request"
64 (T.pack $ currentExchange args)
69 , msgCorrelationID = corrid args
70 , msgExpiration = msgexp args
71 , msgTimestamp = Just now
72 , msgHeaders = msgheader args
74 hr "waiting for answer"
77 (threadDelay (floor (1000000 * rpc_timeout args)) >>
78 throwTo tid TimeoutException)
80 (forever $ threadDelay 200000)
82 ec <- exceptionHandler x
83 hr "closing connection"
85 printparam "exiting" ec
88 exceptionHandler :: RpcException -> IO (ExitCode)
89 exceptionHandler ReceivedException = hr "success" >> (return ExitSuccess)
90 exceptionHandler TimeoutException = hr "timeout" >> (return $ ExitFailure 1)
92 rpcClientCallback :: Handle -> ThreadId -> Args -> (Message, Envelope) -> IO ()
93 rpcClientCallback h tid a m@(_, env) = do
94 let numstring = show $ envDeliveryTag env
95 hr $ "received " ++ numstring
99 (printmsg (Just h) m (anRiss a) now)
100 (\x -> X.throwTo tid (x :: X.IOException) >> return ([], []))
101 throwTo tid ReceivedException
108 instance X.Exception RpcException