Advertisement
NLinker

RunLight

Dec 21st, 2016
181
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. {-# LANGUAGE OverloadedStrings #-}
  2. {-# LANGUAGE FlexibleContexts #-}
  3. {-# LANGUAGE ScopedTypeVariables #-}
  4. {-# OPTIONS_GHC -fno-warn-unused-binds #-}
  5. -- -fno-warn-unused-matches.
  6.  
  7. module Vertigo.Dsl.RunLight (runLight) where
  8.  
  9. import           Control.Exception           (SomeException(..), throw)
  10. import           Control.Exception.Enclosed  (tryAny)
  11. import           Control.Lens                ((&), (?~), (^.), view)
  12. import           Control.Monad.Except        (MonadError, lift)
  13. import           Control.Monad.Free          (iterM)
  14. import           Control.Monad.Catch         (MonadThrow)
  15. import           Control.Monad.IO.Class      (MonadIO, liftIO)
  16. import           Control.Monad.Reader        (MonadReader, ask, asks)
  17. import           Control.Monad.Trans.Control (MonadBaseControl)
  18. import           Control.Monad.Trans.Resource(runResourceT)
  19. import           Data.HashMap.Strict         (toList)
  20. import           Data.Aeson                  (decode, encode)
  21. import           Data.Maybe                  (fromMaybe, fromJust)
  22. import           Data.Monoid                 ((<>))
  23. import           Data.Text                   (Text, pack, unpack)
  24. import           Data.Text.Encoding          (encodeUtf8)
  25. import           Network.HTTP.Client         (Manager, Request(..), Response(..))
  26. import           Network.HTTP.Conduit        (RequestBody(..), httpLbs, parseUrl)
  27.  
  28. import qualified Data.ByteString.Char8        as B
  29. import qualified Data.Map                     as M
  30. import qualified System.Logging.Facade        as Log
  31.  
  32. import           Vertigo.Dsl.Notify
  33. import           Vertigo.Ext                  (Ext, awsEnv, manager, userServiceUrl)
  34. import           Vertigo.Token                (createToken)
  35. import           Vertigo.Types.DeviceInfo
  36. import           Vertigo.Types.Error          (MyException(MyException), ErrorEnum (..))
  37.  
  38. import qualified Vertigo.Types.Notification.Ids      as N
  39. import qualified Vertigo.Types.Notification.UserCore as N
  40. import qualified Vertigo.Types.Notification.Vuid     as N
  41.  
  42. -- run the service without SNS, it's behavior is emulated
  43. runLight :: (MonadBaseControl IO m, MonadError ErrorEnum m, MonadIO m, MonadReader Ext m, MonadThrow m, Log.Logging m) =>
  44.   FreeNotifyDsl a -> m a
  45. runLight fnd = do
  46.   -- m is the manager from Ext
  47.   m <- asks (^. manager)
  48.   iterM (run m) fnd
  49.   where
  50.     run :: (MonadBaseControl IO m, MonadError ErrorEnum m, MonadIO m, MonadReader Ext m, MonadThrow m, Log.Logging m) =>
  51.       Manager -> NotifyDsl (m a) -> m a
  52.     run m (UserServiceGetUser uid next) = do
  53.       let meth = "UserServiceGetDevices: "
  54.       Log.debug $ meth <> show uid
  55.       user0 <- userServiceGetUser_ m uid
  56.       Log.debug $ meth <> show user0
  57.       case user0 of
  58.         Left err -> do
  59.           Log.debug $ meth <> " err = " <> show err
  60.           next Nothing
  61.         Right usr -> next $ Just usr
  62.     run m (UserServiceGetDevices uid next) = do
  63.       let meth = "UserServiceGetDevices: "
  64.       Log.debug $ meth <> show uid
  65.       devices0 <- userServiceGetDevices_ m uid
  66.       Log.debug $ meth <> show devices0
  67.       case devices0 of
  68.         Left err -> do
  69.           Log.debug $ meth <> show err
  70.           next Nothing
  71.         Right des -> next $ Just des
  72.     run m (UserServiceUpdateDevice uid device next) = do
  73.       let meth = "UserServiceUpdateDevice: "
  74.       Log.debug $ meth <> show uid
  75.       r0 <- userServiceUpdateDevice_ m uid device
  76.       Log.debug $ meth <> show r0
  77.       next
  78.     run _m (SnsCreatePlatformEndpoint applicationArn deviceToken customData next) = do
  79.       let meth = "SnsCreatePlatformEndpoint: "
  80.       Log.debug $ meth <> show applicationArn
  81.       r0 <- snsCreatePlatformEndpoint_ applicationArn deviceToken customData
  82.       case r0 of
  83.         Left err -> do
  84.           Log.debug $ meth <> show err
  85.           next Nothing
  86.         Right endpArn -> next $ Just endpArn
  87.     run _m (SnsPublish endpointArn msg next) = do
  88.       let meth = "SnsPublish: "
  89.       Log.debug $ meth <> show (endpointArn, msg)
  90.       r0 <- snsPublish_ endpointArn msg
  91.       case r0 of
  92.         Left err -> do
  93.           Log.debug $ meth <> show err
  94.           next Nothing
  95.         Right _ -> next $ Just ()
  96.     run _m (SnsGetEndpointAttributes endpointArn next) = do
  97.       let meth = "SnsGetEndpointAttributes: "
  98.       Log.debug $ meth <> show endpointArn
  99.       r0 <- snsGetEndpointAttributes_ endpointArn
  100.       Log.debug $ meth <> show r0
  101.       case r0 of
  102.         Left err -> do
  103.           Log.debug $ meth <> show err
  104.           next Nothing
  105.         Right attributes ->
  106.           next $ Just attributes
  107.     run _m (SnsDeleteEndpoint endpointArn next) = do
  108.       let meth = "SnsDeleteEndpoint: "
  109.       Log.debug $ meth <> show endpointArn
  110.       r0 <- snsDeleteEndpoint_ endpointArn
  111.       Log.debug $ meth <> show r0
  112.       case r0 of
  113.         Left err -> Log.debug $ meth <> show err
  114.         Right _ -> return ()
  115.       next
  116. -- concatenate and create access token for other services call
  117. prepareRequest :: MonadThrow m => Text -> Ext -> Text -> m Request
  118. prepareRequest endpoint ext token = do
  119.   let url = ext ^. userServiceUrl
  120.   rq <- parseUrl $ unpack $ url <> endpoint
  121.   return rq
  122.     { redirectCount = 0
  123.     , requestHeaders = ("X-Access-Token", encodeUtf8 token): requestHeaders rq
  124.     }
  125.  
  126. -- call to http://user.qavmg.com/rest/profile/305bc11d-66dd-4577-84c9-2af0b3578949
  127. userServiceGetUser_ :: (MonadBaseControl IO m, MonadIO m, MonadReader Ext m,  MonadThrow m, Log.Logging m) =>
  128.   Manager -> N.UserId -> m (Either SomeException N.UserCore)
  129. userServiceGetUser_ manager uid = tryAny $ do
  130.   ext <- ask
  131.   token <- createToken uid
  132.   let N.UserId vid = uid
  133.   rawJson <- liftIO $ runResourceT $ do
  134.     req <- prepareRequest ("/profile/" <> N.toText vid) ext token
  135.     lift $ Log.debug $ "req = " <> show req
  136.     res <- httpLbs req manager
  137.     return $ responseBody res
  138.   let usrMb = decode rawJson :: Maybe N.UserCore
  139.   return $ fromMaybe (throw $ MyException "User not found") usrMb
  140.  
  141. -- call to http://user.qavmg.com/rest/device
  142. -- token is the user
  143. userServiceGetDevices_ :: (MonadBaseControl IO m, MonadIO m, MonadReader Ext m,  MonadThrow m, Log.Logging m) =>
  144.   Manager -> N.UserId -> m (Either SomeException [DeviceInfo])
  145. userServiceGetDevices_ manager uid = tryAny $ do
  146.   ext <- ask
  147.   token <- createToken uid
  148.   rawJson <- liftIO $ runResourceT $ do
  149.     req <- prepareRequest "/device" ext token
  150.     lift $ Log.debug $ "req = " <> show req
  151.     res <- httpLbs req manager
  152.     return $ responseBody res
  153.   let dsMb = decode rawJson :: Maybe [DeviceInfo]
  154.   return $ fromMaybe [] dsMb
  155.  
  156. -- | userServiceUpdateDevice
  157. -- update the device info
  158. userServiceUpdateDevice_ :: (MonadBaseControl IO m, MonadIO m, MonadReader Ext m, MonadThrow m, Log.Logging m) =>
  159.   Manager -> N.UserId -> DeviceInfo -> m (Either SomeException ())
  160. userServiceUpdateDevice_ manager uid device = tryAny $ do
  161.   ext <- ask
  162.   token <- createToken uid
  163.   _rawJson <- liftIO $ runResourceT $ do
  164.     req <- prepareRequest_ ext token device
  165.     lift $ Log.debug $ "req = " <> show req
  166.     res <- httpLbs req manager
  167.     return $ responseBody res
  168.   return ()
  169.   where
  170.     prepareRequest_ ext token device = do
  171.       let url = ext ^. userServiceUrl
  172.       req0 <- parseUrl $ unpack url
  173.       -- update should be in the form of PUT /rest/device/123456 where 123456 is diDeviceId
  174.       let newPath :: B.ByteString
  175.           newPath = path req0 <> "/device/" <> encodeUtf8 (device ^. diDeviceId)
  176.       return req0
  177.         { method = "PUT"
  178.         , path = newPath
  179.         , redirectCount = 0
  180.         , requestBody = RequestBodyLBS $ encode device
  181.         , requestHeaders =
  182.             ("X-Access-Token", encodeUtf8 token):
  183.             ("Content-Type", "application/json"):
  184.             requestHeaders req0
  185.         }
  186.  
  187. -- paArn - platformApplicationARN
  188. -- deviceToken - device token for iOS or registrationId for Android
  189. snsCreatePlatformEndpoint_ :: (MonadBaseControl IO m, MonadIO m, MonadReader Ext m, Log.Logging m) =>
  190.   ApplicationArn -> DeviceToken -> Text -> m (Either SomeException EndpointArn)
  191. snsCreatePlatformEndpoint_ (ApplicationArn paArn) (DeviceToken deviceToken) customData = tryAny $ do
  192.   -- TODO return arn:aws:sns:us-west-2:877422789438:endpoint/APNS/vertigo-ios-dev-prod/610edbfa-b5ca-3275-ab07-100a5c10310f
  193.   EndpointArn <$> return "arn:aws:sns:us-west-2:877422789438:endpoint/APNS/vertigo-ios-dev-prod/610edbfa-b5ca-3275-ab07-100a5c10310f"
  194.  
  195. -- endpointArn - endpointArn of the device to send message to
  196. -- msq - message to send
  197. snsPublish_ :: (MonadBaseControl IO m, MonadIO m, MonadReader Ext m) =>
  198.   EndpointArn -> Text -> m (Either SomeException ())
  199. snsPublish_ (EndpointArn endpointArn) msg = tryAny $ do
  200.   return ()
  201.  
  202. snsGetEndpointAttributes_ :: (MonadBaseControl IO m, MonadIO m, MonadReader Ext m) =>
  203.   EndpointArn -> m (Either SomeException (M.Map Text Text))
  204. snsGetEndpointAttributes_ (EndpointArn endpointArn) = tryAny $ do
  205.   return $ M.fromList $ [(pack "size", pack "10")]
  206.  
  207. snsDeleteEndpoint_ :: (MonadBaseControl IO m, MonadIO m, MonadReader Ext m) =>
  208.   EndpointArn -> m (Either SomeException ())
  209. snsDeleteEndpoint_ (EndpointArn endpointArn) = tryAny $ do
  210.   return ()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement