grapesy-1.0.0: interop/Interop/Server/TestService/UnaryCall.hs
{-# LANGUAGE OverloadedStrings #-}
module Interop.Server.TestService.UnaryCall (handle) where
import Network.GRPC.Common
import Network.GRPC.Common.Protobuf
import Network.GRPC.Common.StreamElem qualified as StreamElem
import Network.GRPC.Server
import Interop.Server.Common
import Interop.Util.Messages
import Proto.API.Interop
-- | Handle @TestService.UnaryCall@
--
-- This is not implemented using the Protobuf communication patterns because
-- we need to deal with metadata.
--
-- <https://github.com/grpc/grpc/blob/master/doc/interop-test-descriptions.md#unarycall>
handle :: Call UnaryCall -> IO ()
handle call = do
-- Send initial metadata, hold on the trailers
trailers <- constructResponseMetadata call
-- Wait for the request
(inboundMeta, request) <- do
streamElem <- recvInputWithMeta call
case StreamElem.value streamElem of
Nothing -> fail "Expected element"
Just x -> return x
-- Check compression of the input
-- <https://github.com/grpc/grpc/blob/master/doc/interop-test-descriptions.md#client_compressed_unary>
let expectCompressed :: Bool
expectCompressed = request ^. #expectCompressed . #value
checkInboundCompression expectCompressed inboundMeta
-- Send response
payload <- payloadOfType (request ^. #responseType) (request ^. #responseSize)
let outboundMeta :: OutboundMeta
outboundMeta = def {
outboundEnableCompression =
request ^. #responseCompressed . #value
}
response :: Proto SimpleResponse
response = defMessage & #payload .~ payload
sendOutputWithMeta call $ StreamElem (outboundMeta, response)
-- Send status and trailers
echoStatus (request ^. #responseStatus)
sendTrailers call trailers