Skip to content

Commit

Permalink
add ServiceBus, v0.5
Browse files Browse the repository at this point in the history
  • Loading branch information
Marco Zocca committed Aug 6, 2023
1 parent caced60 commit 40d0bed
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 5 deletions.
1 change: 1 addition & 0 deletions ms-azure-api/ms-azure-api.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ library
, containers
, exceptions >= 0.10.4
, hoauth2 == 2.6.0
, http-client
, http-client-tls >= 0.3.6.1
, http-types
, modern-uri
Expand Down
41 changes: 38 additions & 3 deletions ms-azure-api/src/MSAzureAPI/Internal/Common.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,17 @@
--
module MSAzureAPI.Internal.Common (
APIPlane(..)
-- ** PUT
, put
-- ** GET
, get
, getBs
, getLbs
-- ** POST
, post
, postSBMessage
-- ** DELETE
, delete
-- * HTTP(S) connections
, run
, withTLS
Expand Down Expand Up @@ -38,12 +44,14 @@ import Data.Maybe (listToMaybe, fromMaybe)
import Data.Char (toLower)

-- aeson
import qualified Data.Aeson as A (ToJSON(..), FromJSON(..), genericParseJSON, defaultOptions, Options(..), withObject, withText, (.:), (.:?), object, (.=), Key, Value(..), camelTo2)
import qualified Data.Aeson as A (ToJSON(..), encode, FromJSON(..), genericParseJSON, defaultOptions, Options(..), withObject, withText, (.:), (.:?), object, (.=), Key, Value(..), camelTo2)
-- bytestring
import qualified Data.ByteString as BS (ByteString)
import qualified Data.ByteString.Char8 as BS8 (pack, unpack)
import qualified Data.ByteString.Lazy as LBS (ByteString)
import qualified Data.ByteString.Lazy.Char8 as LBS8 (pack, unpack, putStrLn)
-- http-client
import qualified Network.HTTP.Client as L (RequestBody(..))
-- http-client-tls
import Network.HTTP.Client.TLS (newTlsManager)
-- hoauth2
Expand All @@ -52,7 +60,7 @@ import Network.OAuth.OAuth2.Internal (AccessToken(..), ExchangeToken(..), Refres
-- modern-uri
-- import Text.URI (URI, mkURI)
-- req
import Network.HTTP.Req (Req, runReq, HttpConfig(..), HttpException(..), defaultHttpConfig, req, Option, (=:), GET(..), POST(..), Url, Scheme(..), useHttpsURI, https, (/:), ReqBodyJson(..), NoReqBody(..), oAuth2Bearer, HttpResponse(..), jsonResponse, JsonResponse, lbsResponse, LbsResponse, bsResponse, BsResponse, responseBody)
import Network.HTTP.Req (Req, runReq, HttpBody(..), HttpConfig(..), HttpException(..), defaultHttpConfig, req, Option, (=:), GET(..), POST(..), PUT(..), DELETE(..), Url, Scheme(..), useHttpsURI, https, (/:), ReqBodyJson(..), NoReqBody(..), oAuth2Bearer, HttpResponse(..), jsonResponse, JsonResponse, lbsResponse, LbsResponse, bsResponse, BsResponse, responseBody)
-- text
import Data.Text (Text, pack, unpack)
-- unliftio
Expand Down Expand Up @@ -110,6 +118,7 @@ tryReq = try
-- https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/control-plane-and-data-plane
data APIPlane = APManagement -- ^ Management plane (@management.azure.com@ endpoints)
| APData Text -- ^ Data plane e.g. FileREST API
| APServiceBus Text -- ^ Data plane for Service Bus. The parameter is the service name


-- | @PUT@
Expand All @@ -118,7 +127,15 @@ put :: (A.FromJSON b, A.ToJSON a) =>
-> [Text] -- ^ URI path segments
-> Option 'Https -- ^ request parameters etc.
-> a -> AccessToken -> Req b
put apiplane paths params bdy tok = responseBody <$> req POST url (ReqBodyJson bdy) jsonResponse opts
put apiplane paths params bdy tok = responseBody <$> req PUT url (ReqBodyJson bdy) jsonResponse opts
where
opts = auth <> params
(url, auth) = msAzureReqConfig apiplane paths tok

-- | @DELETE@
delete :: (A.FromJSON b, A.ToJSON a) =>
APIPlane -> [Text] -> Option 'Https -> a -> AccessToken -> Req b
delete apiplane paths params bdy tok = responseBody <$> req DELETE url (ReqBodyJson bdy) jsonResponse opts
where
opts = auth <> params
(url, auth) = msAzureReqConfig apiplane paths tok
Expand All @@ -135,6 +152,23 @@ post apiplane paths params bdy tok = responseBody <$> req POST url (ReqBodyJson
opts = auth <> params
(url, auth) = msAzureReqConfig apiplane paths tok

-- | Post a message or batch thereof to the Service Bus
--
-- see example : https://learn.microsoft.com/en-us/rest/api/servicebus/send-message-batch#example
postSBMessage :: (A.FromJSON b, A.ToJSON a) =>
Text
-> [Text]
-> Option 'Https -> a -> AccessToken -> Req b
postSBMessage servName paths params bdy tok = responseBody <$> req POST url (ReqBodyServiceBusMessage bdy) jsonResponse opts
where
opts = auth <> params
(url, auth) = msAzureReqConfig (APServiceBus servName) paths tok

data ReqBodyServiceBusMessage a = ReqBodyServiceBusMessage a
instance A.ToJSON a => HttpBody (ReqBodyServiceBusMessage a) where
getRequestBody (ReqBodyServiceBusMessage a) = L.RequestBodyLBS (A.encode a)
getRequestContentType _ = Just "application/vnd.microsoft.servicebus.json"

-- | @GET@
get :: (A.FromJSON b) =>
APIPlane
Expand All @@ -154,6 +188,7 @@ msAzureReqConfig apiplane uriRest (AccessToken ttok) = (url, os)
urlBase = case apiplane of
APManagement -> "management.azure.com"
APData ub -> ub
APServiceBus sn -> sn <> ".servicebus.windows.net"
url = (https urlBase) //: uriRest
os = oAuth2Bearer $ BS8.pack (unpack ttok)

Expand Down
22 changes: 20 additions & 2 deletions ms-azure-api/src/MSAzureAPI/ServiceBus.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ module MSAzureAPI.ServiceBus where
import GHC.Generics (Generic(..))

-- aeson
import qualified Data.Aeson as A (ToJSON(..), genericToJSON, object, (.=), ToJSONKey(..), FromJSON(..), genericParseJSON, encode)
import qualified Data.Aeson as A (ToJSON(..), genericToJSON, object, (.=), ToJSONKey(..), FromJSON(..), genericParseJSON)
-- containers
import qualified Data.Map as M (Map, singleton, fromList)
-- hoauth2
import Network.OAuth.OAuth2.Internal (AccessToken(..))

-- req
import Network.HTTP.Req (HttpException, runReq, HttpConfig, defaultHttpConfig, Req, Url, Option, Scheme(..), header, (=:))
-- text
Expand All @@ -17,7 +18,24 @@ import Data.Time (UTCTime, getCurrentTime)
import Data.Time.Format (FormatTime, formatTime, defaultTimeLocale)
import Data.Time.LocalTime (getZonedTime)

import MSAzureAPI.Internal.Common (run, APIPlane(..), Location(..), locationDisplayName, (==:), get, getBs, post, getLbs, put, tryReq, aesonOptions)
import MSAzureAPI.Internal.Common (run, APIPlane(..), Location(..), locationDisplayName, (==:), get, getBs, post, postSBMessage, getLbs, put, tryReq, aesonOptions)

-- | Send a message batch to the service bus
--
-- https://learn.microsoft.com/en-us/rest/api/servicebus/send-message-batch#request
sendMessageBatch :: (A.ToJSON a) =>
Text -- ^ namespace
-> Text -- ^ queue name
-> Text -- ^ topic
-> Option 'Https
-> MessageBatch a
-> AccessToken -> Req ()
sendMessageBatch sn qname topic = postSBMessage sn [
qpt
, "messages"
]
where
qpt = qname <> "|" <> topic


newtype MessageBatch a = MessageBatch [a] deriving (Eq, Show)
Expand Down

0 comments on commit 40d0bed

Please sign in to comment.