packages feed

consul-haskell 0.2.1 → 0.3

raw patch · 5 files changed

+257/−129 lines, 5 filesdep +connectiondep +eitherdep +http-client-tlsdep ~monad-controlPVP ok

version bump matches the API change (PVP)

Dependencies added: connection, either, http-client-tls

Dependency ranges changed: monad-control

API changes (from Hackage documentation)

- Network.Consul: Consistent :: Consistency
- Network.Consul: ConsulClient :: Manager -> Text -> PortNumber -> ConsulClient
- Network.Consul: Datacenter :: Text -> Datacenter
- Network.Consul: Default :: Consistency
- Network.Consul: KeyValue :: Word64 -> Word64 -> Word64 -> ByteString -> Word64 -> Maybe Text -> Text -> KeyValue
- Network.Consul: KeyValuePut :: Text -> ByteString -> Maybe Word64 -> Maybe Word64 -> KeyValuePut
- Network.Consul: Session :: Text -> Maybe Word64 -> Session
- Network.Consul: Stale :: Consistency
- Network.Consul: ccHostname :: ConsulClient -> Text
- Network.Consul: ccManager :: ConsulClient -> Manager
- Network.Consul: ccPort :: ConsulClient -> PortNumber
- Network.Consul: data Consistency
- Network.Consul: data ConsulClient
- Network.Consul: data Datacenter
- Network.Consul: data KeyValue
- Network.Consul: data KeyValuePut
- Network.Consul: data Session
- Network.Consul: kvCreateIndex :: KeyValue -> Word64
- Network.Consul: kvFlags :: KeyValue -> Word64
- Network.Consul: kvKey :: KeyValue -> Text
- Network.Consul: kvLockIndex :: KeyValue -> Word64
- Network.Consul: kvModifyIndex :: KeyValue -> Word64
- Network.Consul: kvSession :: KeyValue -> Maybe Text
- Network.Consul: kvValue :: KeyValue -> ByteString
- Network.Consul: kvpCasIndex :: KeyValuePut -> Maybe Word64
- Network.Consul: kvpFlags :: KeyValuePut -> Maybe Word64
- Network.Consul: kvpKey :: KeyValuePut -> Text
- Network.Consul: kvpValue :: KeyValuePut -> ByteString
- Network.Consul: msSession :: ManagedSession -> Session
- Network.Consul: msThreadId :: ManagedSession -> ThreadId
- Network.Consul: sCreateIndex :: Session -> Maybe Word64
- Network.Consul: sId :: Session -> Text
- Network.Consul.Types: cBootstrap :: Config -> Bool
- Network.Consul.Types: cCheckId :: Check -> Text
- Network.Consul.Types: cClientAddr :: Config -> Text
- Network.Consul.Types: cDataDir :: Config -> Text
- Network.Consul.Types: cDatacenter :: Config -> Datacenter
- Network.Consul.Types: cName :: Check -> Maybe Text
- Network.Consul.Types: cNode :: Check -> Text
- Network.Consul.Types: cNotes :: Check -> Maybe Text
- Network.Consul.Types: cOutput :: Check -> Text
- Network.Consul.Types: cServer :: Config -> Bool
- Network.Consul.Types: cServiceId :: Check -> Maybe Text
- Network.Consul.Types: cServiceName :: Check -> Text
- Network.Consul.Types: cStatus :: Check -> HealthCheckStatus
- Network.Consul.Types: ccHostname :: ConsulClient -> Text
- Network.Consul.Types: ccManager :: ConsulClient -> Manager
- Network.Consul.Types: ccPort :: ConsulClient -> PortNumber
- Network.Consul.Types: hChecks :: Health -> [Check]
- Network.Consul.Types: hNode :: Health -> Node
- Network.Consul.Types: hService :: Health -> Service
- Network.Consul.Types: instance Enum Consistency
- Network.Consul.Types: instance Enum HealthCheckStatus
- Network.Consul.Types: instance Enum SessionBehavior
- Network.Consul.Types: instance Eq Consistency
- Network.Consul.Types: instance Eq Datacenter
- Network.Consul.Types: instance Eq HealthCheck
- Network.Consul.Types: instance Eq HealthCheckStatus
- Network.Consul.Types: instance Eq KeyValue
- Network.Consul.Types: instance Eq SessionBehavior
- Network.Consul.Types: instance Eq SessionInfo
- Network.Consul.Types: instance FromJSON Check
- Network.Consul.Types: instance FromJSON Config
- Network.Consul.Types: instance FromJSON Datacenter
- Network.Consul.Types: instance FromJSON Health
- Network.Consul.Types: instance FromJSON HealthCheckStatus
- Network.Consul.Types: instance FromJSON KeyValue
- Network.Consul.Types: instance FromJSON Member
- Network.Consul.Types: instance FromJSON Node
- Network.Consul.Types: instance FromJSON Self
- Network.Consul.Types: instance FromJSON Service
- Network.Consul.Types: instance FromJSON Session
- Network.Consul.Types: instance FromJSON SessionBehavior
- Network.Consul.Types: instance FromJSON SessionInfo
- Network.Consul.Types: instance FromJSON SessionInfoList
- Network.Consul.Types: instance Ord Consistency
- Network.Consul.Types: instance Ord Datacenter
- Network.Consul.Types: instance Ord HealthCheck
- Network.Consul.Types: instance Ord HealthCheckStatus
- Network.Consul.Types: instance Ord SessionBehavior
- Network.Consul.Types: instance Show Consistency
- Network.Consul.Types: instance Show Datacenter
- Network.Consul.Types: instance Show HealthCheck
- Network.Consul.Types: instance Show HealthCheckStatus
- Network.Consul.Types: instance Show KeyValue
- Network.Consul.Types: instance Show Member
- Network.Consul.Types: instance Show Self
- Network.Consul.Types: instance Show Session
- Network.Consul.Types: instance Show SessionBehavior
- Network.Consul.Types: instance Show SessionInfo
- Network.Consul.Types: instance ToJSON (Either (Text, Text) Text)
- Network.Consul.Types: instance ToJSON HealthCheck
- Network.Consul.Types: instance ToJSON RegisterHealthCheck
- Network.Consul.Types: instance ToJSON RegisterService
- Network.Consul.Types: instance ToJSON SessionBehavior
- Network.Consul.Types: instance ToJSON SessionRequest
- Network.Consul.Types: kvCreateIndex :: KeyValue -> Word64
- Network.Consul.Types: kvFlags :: KeyValue -> Word64
- Network.Consul.Types: kvKey :: KeyValue -> Text
- Network.Consul.Types: kvLockIndex :: KeyValue -> Word64
- Network.Consul.Types: kvModifyIndex :: KeyValue -> Word64
- Network.Consul.Types: kvSession :: KeyValue -> Maybe Text
- Network.Consul.Types: kvValue :: KeyValue -> ByteString
- Network.Consul.Types: kvpCasIndex :: KeyValuePut -> Maybe Word64
- Network.Consul.Types: kvpFlags :: KeyValuePut -> Maybe Word64
- Network.Consul.Types: kvpKey :: KeyValuePut -> Text
- Network.Consul.Types: kvpValue :: KeyValuePut -> ByteString
- Network.Consul.Types: mAddress :: Member -> Text
- Network.Consul.Types: mDelegateCur :: Member -> Int
- Network.Consul.Types: mDelegateMax :: Member -> Int
- Network.Consul.Types: mDelegateMin :: Member -> Int
- Network.Consul.Types: mName :: Member -> Text
- Network.Consul.Types: mPort :: Member -> Int
- Network.Consul.Types: mProtocolCur :: Member -> Int
- Network.Consul.Types: mProtocolMax :: Member -> Int
- Network.Consul.Types: mProtocolMin :: Member -> Int
- Network.Consul.Types: mStatus :: Member -> Int
- Network.Consul.Types: mTags :: Member -> Object
- Network.Consul.Types: nAddress :: Node -> Text
- Network.Consul.Types: nNode :: Node -> Text
- Network.Consul.Types: rhcId :: RegisterHealthCheck -> Text
- Network.Consul.Types: rhcInterval :: RegisterHealthCheck -> Maybe Text
- Network.Consul.Types: rhcName :: RegisterHealthCheck -> Text
- Network.Consul.Types: rhcNotes :: RegisterHealthCheck -> Text
- Network.Consul.Types: rhcScript :: RegisterHealthCheck -> Maybe Text
- Network.Consul.Types: rhcTtl :: RegisterHealthCheck -> Maybe Text
- Network.Consul.Types: rrAddress :: RegisterRequest -> Text
- Network.Consul.Types: rrCheck :: RegisterRequest -> Maybe Check
- Network.Consul.Types: rrDatacenter :: RegisterRequest -> Maybe Datacenter
- Network.Consul.Types: rrNode :: RegisterRequest -> Text
- Network.Consul.Types: rrService :: RegisterRequest -> Maybe Service
- Network.Consul.Types: rsCheck :: RegisterService -> Maybe HealthCheck
- Network.Consul.Types: rsId :: RegisterService -> Maybe Text
- Network.Consul.Types: rsName :: RegisterService -> Text
- Network.Consul.Types: rsPort :: RegisterService -> Maybe Int16
- Network.Consul.Types: rsTags :: RegisterService -> [Text]
- Network.Consul.Types: sCreateIndex :: Session -> Maybe Word64
- Network.Consul.Types: sId :: Session -> Text
- Network.Consul.Types: sKey :: Sequencer -> Text
- Network.Consul.Types: sLockIndex :: Sequencer -> Word64
- Network.Consul.Types: sMember :: Self -> Member
- Network.Consul.Types: sSession :: Sequencer -> Session
- Network.Consul.Types: seId :: Service -> Text
- Network.Consul.Types: sePort :: Service -> Maybe Int
- Network.Consul.Types: seService :: Service -> Text
- Network.Consul.Types: seTags :: Service -> [Text]
- Network.Consul.Types: siBehavior :: SessionInfo -> Maybe SessionBehavior
- Network.Consul.Types: siChecks :: SessionInfo -> [Text]
- Network.Consul.Types: siCreateIndex :: SessionInfo -> Word64
- Network.Consul.Types: siId :: SessionInfo -> Text
- Network.Consul.Types: siLockDelay :: SessionInfo -> Maybe Word64
- Network.Consul.Types: siName :: SessionInfo -> Maybe Text
- Network.Consul.Types: siNode :: SessionInfo -> Text
- Network.Consul.Types: siTtl :: SessionInfo -> Maybe Text
- Network.Consul.Types: srBehavor :: SessionRequest -> Maybe SessionBehavior
- Network.Consul.Types: srChecks :: SessionRequest -> [Text]
- Network.Consul.Types: srLockDelay :: SessionRequest -> Maybe Text
- Network.Consul.Types: srName :: SessionRequest -> Maybe Text
- Network.Consul.Types: srNode :: SessionRequest -> Maybe Node
- Network.Consul.Types: srTtl :: SessionRequest -> Maybe Text
+ Network.Consul: [msSession] :: ManagedSession -> Session
+ Network.Consul: [msThreadId] :: ManagedSession -> ThreadId
+ Network.Consul: getService :: MonadIO m => ConsulClient -> Text -> Maybe Text -> Maybe Datacenter -> m (Maybe [ServiceResult])
+ Network.Consul: getServiceHealth :: MonadIO m => ConsulClient -> Text -> m (Maybe [Health])
+ Network.Consul: initializeTlsConsulClient :: MonadIO m => Text -> PortNumber -> Maybe Manager -> m ConsulClient
+ Network.Consul: passHealthCheck :: MonadIO m => ConsulClient -> Text -> Maybe Datacenter -> m ()
+ Network.Consul: runService :: (MonadBaseControl IO m, MonadIO m) => ConsulClient -> RegisterService -> m () -> Maybe Datacenter -> m ()
+ Network.Consul.Internal: getService :: MonadIO m => Manager -> Text -> PortNumber -> Text -> Maybe Text -> Maybe Datacenter -> m (Maybe [ServiceResult])
+ Network.Consul.Internal: hostWithScheme :: ConsulClient -> Text
+ Network.Consul.Types: Critical :: HealthCheckStatus
+ Network.Consul.Types: Passing :: HealthCheckStatus
+ Network.Consul.Types: ServiceResult :: Text -> Text -> Text -> Text -> [Text] -> Maybe Text -> Maybe Int -> ServiceResult
+ Network.Consul.Types: Unknown :: HealthCheckStatus
+ Network.Consul.Types: Warning :: HealthCheckStatus
+ Network.Consul.Types: [cBootstrap] :: Config -> Bool
+ Network.Consul.Types: [cCheckId] :: Check -> Text
+ Network.Consul.Types: [cClientAddr] :: Config -> Text
+ Network.Consul.Types: [cDataDir] :: Config -> Text
+ Network.Consul.Types: [cDatacenter] :: Config -> Datacenter
+ Network.Consul.Types: [cName] :: Check -> Maybe Text
+ Network.Consul.Types: [cNode] :: Check -> Text
+ Network.Consul.Types: [cNotes] :: Check -> Maybe Text
+ Network.Consul.Types: [cOutput] :: Check -> Text
+ Network.Consul.Types: [cServer] :: Config -> Bool
+ Network.Consul.Types: [cServiceId] :: Check -> Maybe Text
+ Network.Consul.Types: [cServiceName] :: Check -> Maybe Text
+ Network.Consul.Types: [cStatus] :: Check -> HealthCheckStatus
+ Network.Consul.Types: [ccHostname] :: ConsulClient -> Text
+ Network.Consul.Types: [ccManager] :: ConsulClient -> Manager
+ Network.Consul.Types: [ccPort] :: ConsulClient -> PortNumber
+ Network.Consul.Types: [ccWithTls] :: ConsulClient -> Bool
+ Network.Consul.Types: [hChecks] :: Health -> [Check]
+ Network.Consul.Types: [hNode] :: Health -> Node
+ Network.Consul.Types: [hService] :: Health -> Service
+ Network.Consul.Types: [kvCreateIndex] :: KeyValue -> Word64
+ Network.Consul.Types: [kvFlags] :: KeyValue -> Word64
+ Network.Consul.Types: [kvKey] :: KeyValue -> Text
+ Network.Consul.Types: [kvLockIndex] :: KeyValue -> Word64
+ Network.Consul.Types: [kvModifyIndex] :: KeyValue -> Word64
+ Network.Consul.Types: [kvSession] :: KeyValue -> Maybe Text
+ Network.Consul.Types: [kvValue] :: KeyValue -> Maybe ByteString
+ Network.Consul.Types: [kvpCasIndex] :: KeyValuePut -> Maybe Word64
+ Network.Consul.Types: [kvpFlags] :: KeyValuePut -> Maybe Word64
+ Network.Consul.Types: [kvpKey] :: KeyValuePut -> Text
+ Network.Consul.Types: [kvpValue] :: KeyValuePut -> ByteString
+ Network.Consul.Types: [mAddress] :: Member -> Text
+ Network.Consul.Types: [mDelegateCur] :: Member -> Int
+ Network.Consul.Types: [mDelegateMax] :: Member -> Int
+ Network.Consul.Types: [mDelegateMin] :: Member -> Int
+ Network.Consul.Types: [mName] :: Member -> Text
+ Network.Consul.Types: [mPort] :: Member -> Int
+ Network.Consul.Types: [mProtocolCur] :: Member -> Int
+ Network.Consul.Types: [mProtocolMax] :: Member -> Int
+ Network.Consul.Types: [mProtocolMin] :: Member -> Int
+ Network.Consul.Types: [mStatus] :: Member -> Int
+ Network.Consul.Types: [mTags] :: Member -> Object
+ Network.Consul.Types: [nAddress] :: Node -> Text
+ Network.Consul.Types: [nNode] :: Node -> Text
+ Network.Consul.Types: [rhcId] :: RegisterHealthCheck -> Text
+ Network.Consul.Types: [rhcInterval] :: RegisterHealthCheck -> Maybe Text
+ Network.Consul.Types: [rhcName] :: RegisterHealthCheck -> Text
+ Network.Consul.Types: [rhcNotes] :: RegisterHealthCheck -> Text
+ Network.Consul.Types: [rhcScript] :: RegisterHealthCheck -> Maybe Text
+ Network.Consul.Types: [rhcTtl] :: RegisterHealthCheck -> Maybe Text
+ Network.Consul.Types: [rrAddress] :: RegisterRequest -> Text
+ Network.Consul.Types: [rrCheck] :: RegisterRequest -> Maybe Check
+ Network.Consul.Types: [rrDatacenter] :: RegisterRequest -> Maybe Datacenter
+ Network.Consul.Types: [rrNode] :: RegisterRequest -> Text
+ Network.Consul.Types: [rrService] :: RegisterRequest -> Maybe Service
+ Network.Consul.Types: [rsCheck] :: RegisterService -> Maybe HealthCheck
+ Network.Consul.Types: [rsId] :: RegisterService -> Maybe Text
+ Network.Consul.Types: [rsName] :: RegisterService -> Text
+ Network.Consul.Types: [rsPort] :: RegisterService -> Maybe Int16
+ Network.Consul.Types: [rsTags] :: RegisterService -> [Text]
+ Network.Consul.Types: [sCreateIndex] :: Session -> Maybe Word64
+ Network.Consul.Types: [sId] :: Session -> Text
+ Network.Consul.Types: [sKey] :: Sequencer -> Text
+ Network.Consul.Types: [sLockIndex] :: Sequencer -> Word64
+ Network.Consul.Types: [sMember] :: Self -> Member
+ Network.Consul.Types: [sSession] :: Sequencer -> Session
+ Network.Consul.Types: [seAddress] :: Service -> Maybe Text
+ Network.Consul.Types: [seId] :: Service -> Text
+ Network.Consul.Types: [sePort] :: Service -> Maybe Int
+ Network.Consul.Types: [seService] :: Service -> Text
+ Network.Consul.Types: [seTags] :: Service -> [Text]
+ Network.Consul.Types: [siBehavior] :: SessionInfo -> Maybe SessionBehavior
+ Network.Consul.Types: [siChecks] :: SessionInfo -> [Text]
+ Network.Consul.Types: [siCreateIndex] :: SessionInfo -> Word64
+ Network.Consul.Types: [siId] :: SessionInfo -> Text
+ Network.Consul.Types: [siLockDelay] :: SessionInfo -> Maybe Word64
+ Network.Consul.Types: [siName] :: SessionInfo -> Maybe Text
+ Network.Consul.Types: [siNode] :: SessionInfo -> Text
+ Network.Consul.Types: [siTtl] :: SessionInfo -> Maybe Text
+ Network.Consul.Types: [srBehavor] :: SessionRequest -> Maybe SessionBehavior
+ Network.Consul.Types: [srChecks] :: SessionRequest -> [Text]
+ Network.Consul.Types: [srLockDelay] :: SessionRequest -> Maybe Text
+ Network.Consul.Types: [srName] :: SessionRequest -> Maybe Text
+ Network.Consul.Types: [srNode] :: SessionRequest -> Maybe Node
+ Network.Consul.Types: [srTtl] :: SessionRequest -> Maybe Text
+ Network.Consul.Types: [srrAddress] :: ServiceResult -> Text
+ Network.Consul.Types: [srrNode] :: ServiceResult -> Text
+ Network.Consul.Types: [srrServiceAddress] :: ServiceResult -> Maybe Text
+ Network.Consul.Types: [srrServiceId] :: ServiceResult -> Text
+ Network.Consul.Types: [srrServiceName] :: ServiceResult -> Text
+ Network.Consul.Types: [srrServicePort] :: ServiceResult -> Maybe Int
+ Network.Consul.Types: [srrServiceTags] :: ServiceResult -> [Text]
+ Network.Consul.Types: data HealthCheckStatus
+ Network.Consul.Types: data ServiceResult
+ Network.Consul.Types: instance Data.Aeson.Types.Class.FromJSON Network.Consul.Types.Check
+ Network.Consul.Types: instance Data.Aeson.Types.Class.FromJSON Network.Consul.Types.Config
+ Network.Consul.Types: instance Data.Aeson.Types.Class.FromJSON Network.Consul.Types.Datacenter
+ Network.Consul.Types: instance Data.Aeson.Types.Class.FromJSON Network.Consul.Types.Health
+ Network.Consul.Types: instance Data.Aeson.Types.Class.FromJSON Network.Consul.Types.HealthCheckStatus
+ Network.Consul.Types: instance Data.Aeson.Types.Class.FromJSON Network.Consul.Types.KeyValue
+ Network.Consul.Types: instance Data.Aeson.Types.Class.FromJSON Network.Consul.Types.Member
+ Network.Consul.Types: instance Data.Aeson.Types.Class.FromJSON Network.Consul.Types.Node
+ Network.Consul.Types: instance Data.Aeson.Types.Class.FromJSON Network.Consul.Types.Self
+ Network.Consul.Types: instance Data.Aeson.Types.Class.FromJSON Network.Consul.Types.Service
+ Network.Consul.Types: instance Data.Aeson.Types.Class.FromJSON Network.Consul.Types.ServiceResult
+ Network.Consul.Types: instance Data.Aeson.Types.Class.FromJSON Network.Consul.Types.Session
+ Network.Consul.Types: instance Data.Aeson.Types.Class.FromJSON Network.Consul.Types.SessionBehavior
+ Network.Consul.Types: instance Data.Aeson.Types.Class.FromJSON Network.Consul.Types.SessionInfo
+ Network.Consul.Types: instance Data.Aeson.Types.Class.FromJSON Network.Consul.Types.SessionInfoList
+ Network.Consul.Types: instance Data.Aeson.Types.Class.ToJSON (Data.Either.Either (Data.Text.Internal.Text, Data.Text.Internal.Text) Data.Text.Internal.Text)
+ Network.Consul.Types: instance Data.Aeson.Types.Class.ToJSON Network.Consul.Types.HealthCheck
+ Network.Consul.Types: instance Data.Aeson.Types.Class.ToJSON Network.Consul.Types.RegisterHealthCheck
+ Network.Consul.Types: instance Data.Aeson.Types.Class.ToJSON Network.Consul.Types.RegisterService
+ Network.Consul.Types: instance Data.Aeson.Types.Class.ToJSON Network.Consul.Types.ServiceResult
+ Network.Consul.Types: instance Data.Aeson.Types.Class.ToJSON Network.Consul.Types.SessionBehavior
+ Network.Consul.Types: instance Data.Aeson.Types.Class.ToJSON Network.Consul.Types.SessionRequest
+ Network.Consul.Types: instance GHC.Classes.Eq Network.Consul.Types.Consistency
+ Network.Consul.Types: instance GHC.Classes.Eq Network.Consul.Types.Datacenter
+ Network.Consul.Types: instance GHC.Classes.Eq Network.Consul.Types.HealthCheck
+ Network.Consul.Types: instance GHC.Classes.Eq Network.Consul.Types.HealthCheckStatus
+ Network.Consul.Types: instance GHC.Classes.Eq Network.Consul.Types.KeyValue
+ Network.Consul.Types: instance GHC.Classes.Eq Network.Consul.Types.SessionBehavior
+ Network.Consul.Types: instance GHC.Classes.Eq Network.Consul.Types.SessionInfo
+ Network.Consul.Types: instance GHC.Classes.Ord Network.Consul.Types.Consistency
+ Network.Consul.Types: instance GHC.Classes.Ord Network.Consul.Types.Datacenter
+ Network.Consul.Types: instance GHC.Classes.Ord Network.Consul.Types.HealthCheck
+ Network.Consul.Types: instance GHC.Classes.Ord Network.Consul.Types.HealthCheckStatus
+ Network.Consul.Types: instance GHC.Classes.Ord Network.Consul.Types.SessionBehavior
+ Network.Consul.Types: instance GHC.Enum.Enum Network.Consul.Types.Consistency
+ Network.Consul.Types: instance GHC.Enum.Enum Network.Consul.Types.HealthCheckStatus
+ Network.Consul.Types: instance GHC.Enum.Enum Network.Consul.Types.SessionBehavior
+ Network.Consul.Types: instance GHC.Show.Show Network.Consul.Types.Check
+ Network.Consul.Types: instance GHC.Show.Show Network.Consul.Types.Consistency
+ Network.Consul.Types: instance GHC.Show.Show Network.Consul.Types.Datacenter
+ Network.Consul.Types: instance GHC.Show.Show Network.Consul.Types.Health
+ Network.Consul.Types: instance GHC.Show.Show Network.Consul.Types.HealthCheck
+ Network.Consul.Types: instance GHC.Show.Show Network.Consul.Types.HealthCheckStatus
+ Network.Consul.Types: instance GHC.Show.Show Network.Consul.Types.KeyValue
+ Network.Consul.Types: instance GHC.Show.Show Network.Consul.Types.Member
+ Network.Consul.Types: instance GHC.Show.Show Network.Consul.Types.Node
+ Network.Consul.Types: instance GHC.Show.Show Network.Consul.Types.Self
+ Network.Consul.Types: instance GHC.Show.Show Network.Consul.Types.Service
+ Network.Consul.Types: instance GHC.Show.Show Network.Consul.Types.ServiceResult
+ Network.Consul.Types: instance GHC.Show.Show Network.Consul.Types.Session
+ Network.Consul.Types: instance GHC.Show.Show Network.Consul.Types.SessionBehavior
+ Network.Consul.Types: instance GHC.Show.Show Network.Consul.Types.SessionInfo
- Network.Consul.Internal: getServiceHealth :: MonadIO m => Manager -> Text -> PortNumber -> Text -> m (Maybe Health)
+ Network.Consul.Internal: getServiceHealth :: MonadIO m => Manager -> Text -> PortNumber -> Text -> m (Maybe [Health])
- Network.Consul.Internal: passHealthCheck :: MonadIO m => Manager -> Text -> PortNumber -> Text -> m ()
+ Network.Consul.Internal: passHealthCheck :: MonadIO m => Manager -> Text -> PortNumber -> Text -> Maybe Datacenter -> m ()
- Network.Consul.Types: Check :: Text -> Text -> Maybe Text -> Maybe Text -> Maybe Text -> HealthCheckStatus -> Text -> Text -> Check
+ Network.Consul.Types: Check :: Text -> Text -> Maybe Text -> Maybe Text -> Maybe Text -> HealthCheckStatus -> Text -> Maybe Text -> Check
- Network.Consul.Types: ConsulClient :: Manager -> Text -> PortNumber -> ConsulClient
+ Network.Consul.Types: ConsulClient :: Manager -> Text -> PortNumber -> Bool -> ConsulClient
- Network.Consul.Types: KeyValue :: Word64 -> Word64 -> Word64 -> ByteString -> Word64 -> Maybe Text -> Text -> KeyValue
+ Network.Consul.Types: KeyValue :: Word64 -> Word64 -> Word64 -> Maybe ByteString -> Word64 -> Maybe Text -> Text -> KeyValue
- Network.Consul.Types: Service :: Text -> Text -> [Text] -> Maybe Int -> Service
+ Network.Consul.Types: Service :: Text -> Text -> [Text] -> Maybe Text -> Maybe Int -> Service

Files

consul-haskell.cabal view
@@ -1,5 +1,5 @@ name:                consul-haskell-version:             0.2.1+version:             0.3 synopsis:            A consul client for Haskell description:   A consul client for Haskell@@ -34,11 +34,14 @@     base                       >= 4.6 && < 5,     base64-bytestring,     bytestring,+    connection,+    either,     http-client,+    http-client-tls,     http-types,     lifted-async,     lifted-base,-    monad-control,+    monad-control >= 1.0,     network,     text,     transformers,
src/Network/Consul.hs view
@@ -10,31 +10,32 @@   , getKey   , getKeys   , getSelf+  , getService+  , getServiceHealth   , getSessionInfo   , getSequencerForLock   , initializeConsulClient+  , initializeTlsConsulClient   , isValidSequencer   , listKeys+  , ManagedSession (..)+  , passHealthCheck   , putKey   , putKeyAcquireLock   , putKeyReleaseLock   , registerService+  , runService   , withManagedSession   , withSequencer   , withSession-  , Consistency(..)-  , ConsulClient(..)-  , Datacenter(..)-  , KeyValue(..)-  , KeyValuePut(..)-  , ManagedSession(..)-  , Session(..)+  , module Network.Consul.Types ) where  import Control.Concurrent hiding (killThread)-import Control.Concurrent.Async.Lifted hiding (cancel)+import Control.Concurrent.Async.Lifted import Control.Concurrent.Lifted (fork, killThread) import Control.Concurrent.STM+import Control.Exception.Lifted import Control.Monad.IO.Class import Control.Monad.Trans.Control import Data.Text (Text)@@ -45,52 +46,99 @@ import qualified Network.Consul.Internal as I import Network.Consul.Types import Network.HTTP.Client (defaultManagerSettings, newManager, Manager)+import Network.HTTP.Client.TLS (tlsManagerSettings) import Network.Socket (PortNumber)   import Prelude hiding (mapM) +parseTtl :: forall t. Integral t => Text -> t+parseTtl ttl = let Right (x,_) = TR.decimal $ T.filter (/= 's') ttl in x+ initializeConsulClient :: MonadIO m => Text -> PortNumber -> Maybe Manager -> m ConsulClient initializeConsulClient hostname port man = do   manager <- liftIO $ case man of                         Just x -> return x                         Nothing -> newManager defaultManagerSettings-  return $ ConsulClient manager hostname port+  return $ ConsulClient manager hostname port False +initializeTlsConsulClient :: MonadIO m => Text -> PortNumber -> Maybe Manager -> m ConsulClient+initializeTlsConsulClient hostname port man = do+    manager <- liftIO $ case man of+                        Just x -> return x+                        Nothing -> newManager tlsManagerSettings+    return $ ConsulClient manager hostname port True  {- Key Value -}- getKey :: MonadIO m => ConsulClient -> Text -> Maybe Word64 -> Maybe Consistency -> Maybe Datacenter -> m (Maybe KeyValue)-getKey _client@ConsulClient{..} = I.getKey ccManager ccHostname ccPort+getKey _client@ConsulClient{..} = I.getKey ccManager (I.hostWithScheme _client) ccPort  getKeys :: MonadIO m => ConsulClient -> Text -> Maybe Word64 -> Maybe Consistency -> Maybe Datacenter -> m [KeyValue]-getKeys _client@ConsulClient{..} = I.getKeys ccManager ccHostname ccPort+getKeys _client@ConsulClient{..} = I.getKeys ccManager (I.hostWithScheme _client) ccPort  listKeys :: MonadIO m => ConsulClient -> Text -> Maybe Word64 -> Maybe Consistency -> Maybe Datacenter -> m [Text]-listKeys _client@ConsulClient{..} = I.listKeys ccManager ccHostname ccPort+listKeys _client@ConsulClient{..} = I.listKeys ccManager (I.hostWithScheme _client) ccPort  putKey :: MonadIO m => ConsulClient -> KeyValuePut -> Maybe Datacenter -> m Bool-putKey _client@ConsulClient{..} = I.putKey ccManager ccHostname ccPort+putKey _client@ConsulClient{..} = I.putKey ccManager (I.hostWithScheme _client) ccPort  putKeyAcquireLock :: MonadIO m => ConsulClient -> KeyValuePut -> Session -> Maybe Datacenter -> m Bool-putKeyAcquireLock _client@ConsulClient{..} = I.putKeyAcquireLock ccManager ccHostname ccPort+putKeyAcquireLock _client@ConsulClient{..} = I.putKeyAcquireLock ccManager (I.hostWithScheme _client) ccPort  putKeyReleaseLock :: MonadIO m => ConsulClient -> KeyValuePut -> Session -> Maybe Datacenter -> m Bool-putKeyReleaseLock _client@ConsulClient{..} = I.putKeyReleaseLock ccManager ccHostname ccPort+putKeyReleaseLock _client@ConsulClient{..} = I.putKeyReleaseLock ccManager (I.hostWithScheme _client) ccPort  deleteKey :: MonadIO m => ConsulClient -> Text -> Bool -> Maybe Datacenter -> m ()-deleteKey _client@ConsulClient{..} key = I.deleteKey ccManager ccHostname ccPort key+deleteKey _client@ConsulClient{..} key = I.deleteKey ccManager (I.hostWithScheme _client) ccPort key +{- Health Checks -}+passHealthCheck :: MonadIO m => ConsulClient -> Text -> Maybe Datacenter -> m ()+passHealthCheck _client@ConsulClient{..} = I.passHealthCheck ccManager (I.hostWithScheme _client) ccPort++getServiceHealth :: MonadIO m => ConsulClient -> Text -> m (Maybe [Health])+getServiceHealth _client@ConsulClient{..} = I.getServiceHealth ccManager (I.hostWithScheme _client) ccPort++{- Catalog -}+getService :: MonadIO m => ConsulClient -> Text -> Maybe Text -> Maybe Datacenter -> m (Maybe [ServiceResult])+getService _client@ConsulClient{..} = I.getService ccManager (I.hostWithScheme _client) ccPort+ {- Agent -} getSelf :: MonadIO m => ConsulClient -> m (Maybe Self)-getSelf _client@ConsulClient{..} = I.getSelf ccManager ccHostname ccPort+getSelf _client@ConsulClient{..} = I.getSelf ccManager (I.hostWithScheme _client) ccPort  registerService :: MonadIO m => ConsulClient -> RegisterService -> Maybe Datacenter -> m Bool-registerService _client@ConsulClient{..} = I.registerService ccManager ccHostname ccPort+registerService _client@ConsulClient{..} = I.registerService ccManager (I.hostWithScheme _client) ccPort +runService :: (MonadBaseControl IO m, MonadIO m) => ConsulClient -> RegisterService -> m () -> Maybe Datacenter -> m ()+runService client request action dc = do+  r <- registerService client request dc+  case r of+    True -> do+      mainFunc <- async action+      checkAction <- case rsCheck request of+                      Just(x@(Ttl _)) -> do+                        a <- async $ ttlFunc x+                        return $ Just a+                      _ -> return Nothing+      _foo :: () <- wait mainFunc+      case checkAction of+        Just a -> cancel a+        Nothing -> return ()+    False -> return ()+  where+    ttlFunc y@(Ttl x) = do+      (do+        let ttl = parseTtl x+        liftIO $ threadDelay $ (ttl - (fromIntegral $ floor (fromIntegral ttl / fromIntegral 2))) * 1000000+        let checkId = T.concat["service:",maybe (rsName request) id (rsId request)]+        passHealthCheck client checkId dc) `catch` (\ e -> do+           let _x :: SomeException = e+           return ())+      ttlFunc y+ {- Session -} getSessionInfo :: MonadIO m => ConsulClient -> Text -> Maybe Datacenter -> m (Maybe [SessionInfo])-getSessionInfo _client@ConsulClient{..} = I.getSessionInfo ccManager ccHostname ccPort+getSessionInfo _client@ConsulClient{..} = I.getSessionInfo ccManager (I.hostWithScheme _client) ccPort  withSession :: forall a m. (MonadIO m,MonadBaseControl IO m) => ConsulClient -> Session -> (Session -> m a) -> m a -> m a withSession client session action lostAction = do@@ -108,12 +156,12 @@       liftIO $ threadDelay (10 * 1000000)       x <- getSessionInfo client (sId session) Nothing       case x of-        Just [] -> cancel var threadVar-        Nothing -> cancel var threadVar+        Just [] -> cancelAction var threadVar+        Nothing -> cancelAction var threadVar         Just _ -> runThread var threadVar -    cancel :: TMVar a -> TMVar ThreadId -> m ()-    cancel resultVar tidVar = do+    cancelAction :: TMVar a -> TMVar ThreadId -> m ()+    cancelAction resultVar tidVar = do       tid <- liftIO $ atomically $ readTMVar tidVar       killThread tid       empty <- liftIO $ atomically $ isEmptyTMVar resultVar@@ -169,7 +217,7 @@ createManagedSession :: MonadIO m => ConsulClient -> Maybe Text -> Text -> m (Maybe ManagedSession) createManagedSession _client@ConsulClient{..} name ttl = do   let r = SessionRequest Nothing name Nothing [] (Just Release) (Just ttl)-  s <- I.createSession ccManager ccHostname ccPort r Nothing+  s <- I.createSession ccManager (I.hostWithScheme _client) ccPort r Nothing   mapM f s   where     f x = do@@ -181,7 +229,7 @@     runThread :: Session -> IO ()     runThread s = do       threadDelay $ (saneTtl - (saneTtl - 10)) * 1000000-      x <- I.renewSession ccManager ccHostname ccPort s Nothing+      x <- I.renewSession ccManager (I.hostWithScheme _client) ccPort s Nothing       case x of         True -> runThread s         False -> return ()@@ -189,4 +237,4 @@ destroyManagedSession :: MonadIO m => ConsulClient -> ManagedSession -> m () destroyManagedSession _client@ConsulClient{..} (ManagedSession session tid) = do   liftIO $ killThread tid-  I.destroySession ccManager ccHostname ccPort session Nothing+  I.destroySession ccManager (I.hostWithScheme _client) ccPort session Nothing
src/Network/Consul/Internal.hs view
@@ -1,8 +1,12 @@+{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE OverloadedStrings #-}  module Network.Consul.Internal (+  --Client+    hostWithScheme+   --Key-Value Store-    deleteKey+  , deleteKey   , getKey   , getKeys   , listKeys@@ -32,12 +36,14 @@    --Catalog   , getDatacenters+  , getService   ) where  import Control.Monad.IO.Class import Data.Aeson (decode,encode) import Data.ByteString (ByteString) import qualified Data.ByteString as B+--import qualified Data.ByteString.Base64 as B64 import qualified Data.ByteString.Lazy as BL import Data.Maybe import Data.Text (Text)@@ -49,9 +55,13 @@ import Network.HTTP.Types import Network.Socket (PortNumber(..)) +hostWithScheme :: ConsulClient -> Text+hostWithScheme ConsulClient{..} = scheme `T.append` ccHostname+  where scheme = if ccWithTls then "https://" else "http://"+ createRequest :: MonadIO m => Text -> PortNumber -> Text -> Maybe Text -> Maybe ByteString -> Bool -> Maybe Datacenter -> m Request-createRequest hostname (PortNum portNumber) endpoint query body wait dc = do-  let baseUrl = T.concat ["http://",hostname,":",T.pack $ show portNumber,endpoint,needQueryString+createRequest hostWithScheme portNumber endpoint query body wait dc = do+  let baseUrl = T.concat [hostWithScheme,":",T.pack $ show portNumber,endpoint,needQueryString                          ,maybe "" id query, prefixAnd, maybe "" (\ (Datacenter x) -> T.concat["dc=",x]) dc]   initReq <- liftIO $ parseUrl $ T.unpack baseUrl   case body of@@ -63,7 +73,7 @@     indef req = if wait == True then req{responseTimeout = Nothing} else req  {- Key Value Store -}-getKey :: MonadIO m => Manager -> Text -> PortNumber -> Text -> Maybe Word64 -> Maybe Consistency -> Maybe Datacenter -> m (Maybe KeyValue)+getKey :: MonadIO m => Manager -> Text -> PortNumber -> Text -> Maybe Word64 -> Maybe Consistency -> Maybe Datacenter -> m (Maybe Network.Consul.Types.KeyValue) getKey manager hostname portnumber key index consistency dc = do   request <- createRequest hostname portnumber (T.concat ["/v1/kv/",key]) fquery Nothing (isJust index) dc   liftIO $ withResponse request manager $ \ response -> do@@ -177,38 +187,37 @@  -}  registerHealthCheck :: MonadIO m => Manager -> Text -> PortNumber -> RegisterHealthCheck -> m ()-registerHealthCheck manager hostname (PortNum portNumber) request = do-  initReq <- liftIO $ parseUrl $ T.unpack $ T.concat ["http://",hostname, ":", T.pack $ show portNumber ,"/v1/agent/check/register"]+registerHealthCheck manager hostname portNumber request = do+  initReq <- liftIO $ parseUrl $ T.unpack $ T.concat [hostname, ":", T.pack $ show portNumber ,"/v1/agent/check/register"]   let httpReq = initReq { method = "PUT", requestBody = RequestBodyBS $ BL.toStrict $ encode request}   liftIO $ withResponse httpReq manager $ \ response -> do     _bodyParts <- brConsume $ responseBody response     return ()  deregisterHealthCheck :: MonadIO m => Manager -> Text -> PortNumber -> Text -> m ()-deregisterHealthCheck manager hostname (PortNum portNumber) checkId = do-  initReq <- liftIO $ parseUrl $ T.unpack $ T.concat ["http://",hostname, ":", T.pack $ show portNumber ,"/v1/agent/check/deregister/", checkId]+deregisterHealthCheck manager hostname portNumber checkId = do+  initReq <- liftIO $ parseUrl $ T.unpack $ T.concat [hostname, ":", T.pack $ show portNumber ,"/v1/agent/check/deregister/", checkId]   liftIO $ withResponse initReq manager $ \ response -> do     _bodyParts <- brConsume $ responseBody response     return ()  -passHealthCheck :: MonadIO m => Manager -> Text -> PortNumber -> Text -> m ()-passHealthCheck manager hostname (PortNum portNumber) checkId = do-  initReq <- liftIO $ parseUrl $ T.unpack $ T.concat ["http://",hostname, ":", T.pack $ show portNumber ,"/v1/agent/check/pass/", checkId]+passHealthCheck :: MonadIO m => Manager -> Text -> PortNumber -> Text -> Maybe Datacenter -> m ()+passHealthCheck manager hostname portNumber checkId dc = do+  initReq <- createRequest hostname portNumber (T.concat ["/v1/agent/check/pass/", checkId]) Nothing Nothing False dc   liftIO $ withResponse initReq manager $ \ response -> do-    _bodyParts <- brConsume $ responseBody response     return ()  warnHealthCheck :: MonadIO m => Manager -> Text -> PortNumber -> Text -> m ()-warnHealthCheck manager hostname (PortNum portNumber) checkId = do-  initReq <- liftIO $ parseUrl $ T.unpack $ T.concat ["http://",hostname, ":", T.pack $ show portNumber ,"/v1/agent/check/warn/", checkId]+warnHealthCheck manager hostname portNumber checkId = do+  initReq <- liftIO $ parseUrl $ T.unpack $ T.concat [hostname, ":", T.pack $ show portNumber ,"/v1/agent/check/warn/", checkId]   liftIO $ withResponse initReq manager $ \ response -> do     _bodyParts <- brConsume $ responseBody response     return ()  failHealthCheck :: MonadIO m => Manager -> Text -> PortNumber -> Text -> m ()-failHealthCheck manager hostname (PortNum portNumber) checkId = do-  initReq <- liftIO $ parseUrl $ T.unpack $ T.concat ["http://",hostname, ":", T.pack $ show portNumber ,"/v1/agent/check/fail/", checkId]+failHealthCheck manager hostname portNumber checkId = do+  initReq <- liftIO $ parseUrl $ T.unpack $ T.concat [hostname, ":", T.pack $ show portNumber ,"/v1/agent/check/fail/", checkId]   liftIO $ withResponse initReq manager $ \ response -> do     _bodyParts <- brConsume $ responseBody response     return ()@@ -222,15 +231,15 @@       _ -> return False  deregisterService :: MonadIO m => Manager -> Text -> PortNumber -> Text -> m ()-deregisterService manager hostname (PortNum portNumber) service = do-  initReq <- liftIO $ parseUrl $ T.unpack $ T.concat ["http://",hostname, ":", T.pack $ show portNumber ,"/v1/agent/service/deregister/", service]+deregisterService manager hostname portNumber service = do+  initReq <- liftIO $ parseUrl $ T.unpack $ T.concat [hostname, ":", T.pack $ show portNumber ,"/v1/agent/service/deregister/", service]   liftIO $ withResponse initReq manager $ \ response -> do     _bodyParts <- brConsume $ responseBody response     return ()  getSelf :: MonadIO m => Manager -> Text -> PortNumber -> m (Maybe Self)-getSelf manager hostname (PortNum portNumber) = do-  initReq <- liftIO $ parseUrl $ T.unpack $ T.concat ["http://",hostname, ":", T.pack $ show portNumber ,"/v1/agent/self"]+getSelf manager hostname portNumber = do+  initReq <- liftIO $ parseUrl $ T.unpack $ T.concat [hostname, ":", T.pack $ show portNumber ,"/v1/agent/self"]   liftIO $ withResponse initReq manager $ \ response -> do     bodyParts <- brConsume $ responseBody response     let body = B.concat bodyParts@@ -239,16 +248,16 @@  {- Health -} getServiceChecks :: MonadIO m => Manager -> Text -> PortNumber -> Text -> m [Check]-getServiceChecks manager hostname (PortNum portNumber) name = do-  initReq <- liftIO $ parseUrl $ T.unpack $ T.concat ["http://",hostname, ":", T.pack $ show portNumber ,"/v1/health/checks/", name]+getServiceChecks manager hostname portNumber name = do+  initReq <- liftIO $ parseUrl $ T.unpack $ T.concat [hostname, ":", T.pack $ show portNumber ,"/v1/health/checks/", name]   liftIO $ withResponse initReq manager $ \ response -> do     bodyParts <- brConsume $ responseBody response     let body = B.concat bodyParts     return $ maybe [] id (decode $ BL.fromStrict body) -getServiceHealth :: MonadIO m => Manager -> Text -> PortNumber -> Text -> m (Maybe Health)-getServiceHealth manager hostname (PortNum portNumber) name = do-  initReq <- liftIO $ parseUrl $ T.unpack $ T.concat ["http://",hostname, ":", T.pack $ show portNumber ,"/v1/health/service/", name]+getServiceHealth :: MonadIO m => Manager -> Text -> PortNumber -> Text -> m (Maybe [Health])+getServiceHealth manager hostname portNumber name = do+  initReq <- liftIO $ parseUrl $ T.unpack $ T.concat [hostname, ":", T.pack $ show portNumber ,"/v1/health/service/", name]   liftIO $ withResponse initReq manager $ \ response -> do     bodyParts <- brConsume $ responseBody response     let body = B.concat bodyParts@@ -292,8 +301,8 @@  {- Catalog -} getDatacenters :: MonadIO m => Manager -> Text -> PortNumber -> m [Datacenter]-getDatacenters manager hostname (PortNum portNumber) = liftIO $ do-  initReq <- parseUrl $ T.unpack $ T.concat ["http://",hostname, ":", T.pack $ show portNumber ,"/v1/catalog/datacenters/"]+getDatacenters manager hostname portNumber = liftIO $ do+  initReq <- parseUrl $ T.unpack $ T.concat [hostname, ":", T.pack $ show portNumber ,"/v1/catalog/datacenters/"]   withResponse initReq manager $ \ response -> do     bodyParts <- brConsume $ responseBody response     let body = B.concat bodyParts@@ -302,3 +311,9 @@       Just x -> return x       Nothing -> return [] +getService :: MonadIO m => Manager -> Text -> PortNumber -> Text -> Maybe Text -> Maybe Datacenter -> m (Maybe [ServiceResult])+getService manager hostname portNumber name tag dc = do+  req <- createRequest hostname portNumber (T.concat["/v1/catalog/service/",name]) (fmap (\ x -> T.concat ["tag=",x]) tag) Nothing False dc+  liftIO $ withResponse req manager $ \ response -> do+    bodyParts <- brConsume $ responseBody response+    return $ decode $ BL.fromStrict $ B.concat bodyParts
src/Network/Consul/Types.hs view
@@ -10,7 +10,8 @@   Datacenter (..),   Health(..),   HealthCheck(..),-  KeyValue(..),+  HealthCheckStatus(..),+  Network.Consul.Types.KeyValue(..),   KeyValuePut(..),   Member(..),   Node(..),@@ -19,6 +20,7 @@   RegisterService(..),   Self(..),   Service(..),+  ServiceResult(..),   Session(..),   SessionBehavior(..),   SessionInfo(..),@@ -31,6 +33,7 @@ #endif import Control.Monad import Data.Aeson+import Data.Aeson.Types import Data.ByteString (ByteString) import qualified Data.ByteString.Base64 as B64 import Data.Foldable@@ -38,14 +41,14 @@ import Data.Text(Text) import qualified Data.Text.Encoding as TE import Data.Word-import Debug.Trace import Network.HTTP.Client (Manager) import Network.Socket  data ConsulClient = ConsulClient{   ccManager :: Manager,   ccHostname :: Text,-  ccPort :: PortNumber+  ccPort :: PortNumber,+  ccWithTls :: Bool }  data Datacenter = Datacenter Text deriving (Eq,Show,Ord)@@ -62,7 +65,7 @@   kvCreateIndex :: Word64,   kvLockIndex :: Word64,   kvModifyIndex :: Word64,-  kvValue :: ByteString,+  kvValue :: Maybe ByteString,   kvFlags :: Word64,   kvSession :: Maybe Text,   kvKey :: Text@@ -120,9 +123,20 @@   seId :: Text,   seService :: Text,   seTags :: [Text],+  seAddress :: Maybe Text,   sePort :: Maybe Int-}+} deriving (Show) +data ServiceResult = ServiceResult{+  srrNode :: Text,+  srrAddress :: Text,+  srrServiceId :: Text,+  srrServiceName :: Text,+  srrServiceTags :: [Text],+  srrServiceAddress :: Maybe Text,+  srrServicePort :: Maybe Int+} deriving (Show)+ data Check = Check {   cNode :: Text,   cCheckId :: Text,@@ -131,13 +145,13 @@   cServiceId :: Maybe Text,   cStatus :: HealthCheckStatus,   cOutput :: Text,-  cServiceName :: Text-}+  cServiceName :: Maybe Text+} deriving (Show)  data Node = Node {   nNode :: Text,   nAddress :: Text-}+} deriving (Show)  {- Agent -} data RegisterHealthCheck = RegisterHealthCheck {@@ -188,7 +202,7 @@   hNode :: Node,   hService :: Service,   hChecks :: [Check]-}+} deriving (Show)   {- JSON Instances -}@@ -205,14 +219,22 @@   parseJSON _ = mzero  instance FromJSON HealthCheckStatus where-  parseJSON (String "Critical") = pure Critical-  parseJSON (String "Passing") = pure Passing-  parseJSON (String "Unknown") = pure Unknown-  parseJSON (String "Warning") = pure Warning+  parseJSON (String "critical") = pure Critical+  parseJSON (String "passing") = pure Passing+  parseJSON (String "unknown") = pure Unknown+  parseJSON (String "warning") = pure Warning   parseJSON _ = mzero -instance FromJSON KeyValue where-  parseJSON (Object v) = KeyValue <$> v .: "CreateIndex" <*> v .: "LockIndex" <*> v .: "ModifyIndex" <*> (foo =<< B64.decode . TE.encodeUtf8 <$> v .: "Value") <*> v .: "Flags" <*> v .:? "Session" <*> v .: "Key"+instance FromJSON Network.Consul.Types.KeyValue where+  parseJSON (Object v) =+    Network.Consul.Types.KeyValue+      <$> v .: "CreateIndex"+      <*> v .: "LockIndex"+      <*> v .: "ModifyIndex"+      <*> (foo =<< (v .:? "Value"))+      <*> v .: "Flags"+      <*> v .:? "Session"+      <*> v .: "Key"   parseJSON _ = mzero  instance FromJSON Datacenter where@@ -220,11 +242,11 @@   parseJSON _ = mzero  instance FromJSON Check where-  parseJSON (Object x) = Check <$> x .: "Node" <*> x .: "CheckId" <*> x .: "Name" <*> x .: "Notes" <*> x .: "ServiceId" <*> x .: "Status" <*> x .: "Output" <*> x .: "ServiceName"+  parseJSON (Object x) = Check <$> x .: "Node" <*> x .: "CheckID" <*> x .: "Name" <*> x .:? "Notes" <*> x .:? "ServiceID" <*> x .: "Status" <*> x .: "Output" <*> x .:? "ServiceName"   parseJSON _ = mzero  instance FromJSON Service where-  parseJSON (Object x) = Service <$> x .: "Id" <*> x .: "Service" <*> x .: "Tags" <*> x .: "Port"+  parseJSON (Object x) = Service <$> x .: "ID" <*> x .: "Service" <*> x .: "Tags" <*> x .:? "Address" <*> x .:? "Port"   parseJSON _ = mzero  instance FromJSON Node where@@ -260,7 +282,7 @@   toJSON (RegisterHealthCheck i name notes script interval ttl) = object ["id" .= i, "name" .= name, "notes" .= notes, "script" .= script, "interval" .= interval, "ttl" .= ttl]  instance ToJSON RegisterService where-  toJSON (RegisterService i name tags port check) = object ["ID" .= i, "Name" .= name, "Tags" .= tags, "Port" .= port, "Check" .= check]+  toJSON (RegisterService i name tags port check) = object ["ID" .= i, "Name" .= name, "tags" .= tags, "port" .= port, "Check" .= check]  instance ToJSON HealthCheck where   toJSON (Ttl x) = object ["TTL" .= x]@@ -274,6 +296,17 @@   toJSON (Left (script,interval)) = object ["Script" .= script, "Interval" .= interval]   toJSON (Right ttl) = object ["TTL" .= ttl] -foo :: Monad m => Either String a -> m a-foo (Left x) = trace "failing" $ fail x-foo (Right x) = return x+instance ToJSON ServiceResult where+  toJSON (ServiceResult node addr sid sName sTags sAddress sPort) = object["Node" .= node, "Address" .= addr, "ServiceID" .= sid, "ServiceName" .= sName, "ServiceTags" .= sTags, "ServiceAddress" .= sAddress, "ServicePort" .= sPort]++instance FromJSON ServiceResult where+  parseJSON (Object x) = ServiceResult <$> x .: "Node" <*> x .: "Address" <*> x .: "ServiceID" <*> x .: "ServiceName" <*> x .: "ServiceTags" <*> x .:? "ServiceAddress" <*> x .:? "ServicePort"+  parseJSON _ = mzero++foo :: Maybe Value -> Parser (Maybe ByteString)+foo (Just (String x)) =+  case B64.decode $ TE.encodeUtf8 x of+    Left y -> fail y+    Right y -> return $ Just y+foo (Just _) = return Nothing+foo Nothing = return Nothing
tests/Main.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE OverloadedStrings #-} import Control.Concurrent import Control.Monad.IO.Class@@ -11,115 +12,144 @@ import Test.Tasty import Test.Tasty.HUnit -manager :: IO Manager-manager = newManager defaultManagerSettings+client :: IO ConsulClient+client = initializeConsulClient "localhost" 8500 Nothing  {- Internal Tests -} internalKVTests :: TestTree-internalKVTests = testGroup "Internal Key Value" [testGetInvalidKey, testPutKey, -  testGetKey,testGetKeys,testListKeys,testDeleteKey]+internalKVTests = testGroup "Internal Key Value" [testGetInvalidKey, testPutKey,+  testGetKey,testGetKeys,testListKeys,testDeleteKey,testGetNullValueKey]  testGetInvalidKey :: TestTree testGetInvalidKey = testCase "testGetInvalidKey" $ do-  man <- manager-  x <- I.getKey man "localhost" (PortNum 8500) "nokey" Nothing Nothing Nothing+  _client@ConsulClient{..} <- client+  x <- I.getKey ccManager (I.hostWithScheme _client) ccPort "nokey" Nothing Nothing Nothing   assertEqual "testGetInvalidKey: Found a key that doesn't exist" x Nothing  testPutKey :: TestTree testPutKey = testCase "testPutKey" $ do-  man <- manager+  _client@ConsulClient{..} <- client   let put = KeyValuePut "/testPutKey" "Test" Nothing Nothing-  x <- I.putKey man "localhost" (PortNum 8500) put Nothing+  x <- I.putKey ccManager (I.hostWithScheme _client) ccPort put Nothing   assertEqual "testPutKey: Write failed" True x  testGetKey :: TestTree testGetKey = testCase "testGetKey" $ do-  man <- manager+  _client@ConsulClient{..} <- client   let put = KeyValuePut "/testGetKey" "Test" Nothing Nothing-  x1 <- I.putKey man "localhost" (PortNum 8500) put Nothing+  x1 <- I.putKey ccManager (I.hostWithScheme _client) ccPort put Nothing   assertEqual "testGetKey: Write failed" True x1-  x2 <- I.getKey man "localhost" (PortNum 8500) "/testGetKey" Nothing Nothing Nothing+  x2 <- I.getKey ccManager (I.hostWithScheme _client) ccPort "/testGetKey" Nothing Nothing Nothing   case x2 of-    Just x -> assertEqual "testGetKey: Incorrect Value" (kvValue x) "Test"+    Just x -> assertEqual "testGetKey: Incorrect Value" (kvValue x) (Just "Test")     Nothing -> assertFailure "testGetKey: No value returned" +testGetNullValueKey :: TestTree+testGetNullValueKey = testCase "testGetNullValueKey" $ do+  _client@ConsulClient{..} <- client+  let put = KeyValuePut "/testGetNullValueKey" "" Nothing Nothing+  x1 <- I.putKey ccManager (I.hostWithScheme _client) ccPort put Nothing+  assertEqual "testGetNullValueKey: Write failed" True x1+  liftIO $ threadDelay (500 * 1000)+  x2 <- I.getKey ccManager (I.hostWithScheme _client) ccPort "/testGetNullValueKey" Nothing Nothing Nothing+  case x2 of+    Just x -> assertEqual "testGetNullValueKey: Incorrect Value" (kvValue x) Nothing+    Nothing -> assertFailure "testGetNullValueKey: No value returned"++ testGetKeys :: TestTree testGetKeys = testCase "testGetKeys" $ do-  man <- manager+  _client@ConsulClient{..} <- client   let put1 = KeyValuePut "/testGetKeys/key1" "Test" Nothing Nothing-  x1 <- I.putKey man "localhost" (PortNum 8500) put1 Nothing+  x1 <- I.putKey ccManager (I.hostWithScheme _client) ccPort put1 Nothing   assertEqual "testGetKeys: Write failed" True x1   let put2 = KeyValuePut "/testGetKeys/key2" "Test" Nothing Nothing-  x2 <- I.putKey man "localhost" (PortNum 8500) put2 Nothing+  x2 <- I.putKey ccManager (I.hostWithScheme _client) ccPort put2 Nothing   assertEqual "testGetKeys: Write failed" True x2-  x3 <- I.getKeys man "localhost" (PortNum 8500) "/testGetKeys" Nothing Nothing Nothing+  x3 <- I.getKeys ccManager (I.hostWithScheme _client) ccPort "/testGetKeys" Nothing Nothing Nothing   assertEqual "testGetKeys: Incorrect number of results" 2 (length x3)  testListKeys :: TestTree testListKeys = testCase "testListKeys" $ do-  man  <- manager+  _client@ConsulClient{..} <- client   let put1 = KeyValuePut "/testListKeys/key1" "Test" Nothing Nothing-  x1 <- I.putKey man "localhost" (PortNum 8500) put1 Nothing+  x1 <- I.putKey ccManager (I.hostWithScheme _client) ccPort put1 Nothing   assertEqual "testListKeys: Write failed" True x1   let put2 = KeyValuePut "/testListKeys/key2" "Test" Nothing Nothing-  x2 <- I.putKey man "localhost" (PortNum 8500) put2 Nothing+  x2 <- I.putKey ccManager (I.hostWithScheme _client) ccPort put2 Nothing   assertEqual "testListKeys: Write failed" True x2-  x3 <- I.listKeys man "localhost" (PortNum 8500) "/testListKeys/" Nothing Nothing Nothing+  x3 <- I.listKeys ccManager (I.hostWithScheme _client) ccPort "/testListKeys/" Nothing Nothing Nothing   assertEqual "testListKeys: Incorrect number of results" 2 (length x3)  testDeleteKey :: TestTree testDeleteKey = testCase "testDeleteKey" $ do-  man  <- manager+  _client@ConsulClient{..} <- client   let put1 = KeyValuePut "/testDeleteKey" "Test" Nothing Nothing-  x1 <- I.putKey man "localhost" (PortNum 8500) put1 Nothing+  x1 <- I.putKey ccManager (I.hostWithScheme _client) ccPort put1 Nothing   assertEqual "testDeleteKey: Write failed" True x1-  I.deleteKey man "localhost" (PortNum 8500) "/testDeleteKey" False Nothing-  x2 <- I.getKey man "localhost" (PortNum 8500) "/testDeleteKey" Nothing Nothing Nothing+  I.deleteKey ccManager (I.hostWithScheme _client) ccPort "/testDeleteKey" False Nothing+  x2 <- I.getKey ccManager (I.hostWithScheme _client) ccPort "/testDeleteKey" Nothing Nothing Nothing   assertEqual "testDeleteKey: Key was not deleted" Nothing x2  {- Agent -} testRegisterService :: TestTree testRegisterService = testCase "testRegisterService" $ do-  man <- manager+  _client@ConsulClient{..} <- client   let req = RegisterService Nothing "testService" ["test"] Nothing (Just $ Ttl "10s")-  val <- I.registerService man "localhost" (PortNum 8500) req Nothing+  val <- I.registerService ccManager (I.hostWithScheme _client) ccPort req Nothing   assertEqual "testRegisterService: Service was not created" val True  testGetSelf :: TestTree testGetSelf = testCase "testGetSelf" $ do-  man <- manager-  x <- I.getSelf man "localhost" (PortNum 8500)+  _client@ConsulClient{..} <- client+  x <- I.getSelf ccManager (I.hostWithScheme _client) ccPort   assertEqual "testGetSelf: Self not returned" True (isJust x)  {- testRegisterHealthCheck :: TestTree testRegisterHealthCheck = testCase "testRegisterHealthCheck" $ do-  man <- manager+  _client@ConsulClient{..} <- client   let check = RegisterHealthCheck "testHealthCheck" "testHealthCheck" "" Nothing Nothing (Just "15s")-  x1 <- I.registerHealthCheck man "localhost" (PortNum 8500) check+  x1 <- I.registerHealthCheck ccManager (I.hostWithScheme _client) ccPort check   undefined -}  {- Health Checks -}---testServiceChecks :: +testGetServiceHealth :: TestTree+testGetServiceHealth = testCase "testGetServiceHealth" $ do+  _client@ConsulClient{..} <- client+  let req = RegisterService (Just "testGetServiceHealth") "testGetServiceHealth" [] Nothing Nothing+  r1 <- I.registerService ccManager (I.hostWithScheme _client) ccPort req Nothing+  case r1 of+    True -> do+      liftIO $ threadDelay 1000000+      r2 <- I.getServiceHealth ccManager (I.hostWithScheme _client) ccPort "testGetServiceHealth"+      case r2 of+        Just [x] -> return ()+        Just [] -> assertFailure "testGetServiceHealth: No Services Returned"+        Nothing -> assertFailure "testGetServiceHealth: Failed to parse result"+    False -> assertFailure "testGetServiceHealth: Service was not created" +testHealth :: TestTree+testHealth = testGroup "Health Check Tests" [testGetServiceHealth]+ {- Session -} testCreateSession :: TestTree testCreateSession = testCase "testCreateSession" $ do-  man <- manager+  _client@ConsulClient{..} <- client   let req = SessionRequest Nothing (Just "testCreateSession") Nothing ["serfHealth"] (Just Release) (Just "30s")-  result <- I.createSession man "localhost" (PortNum 8500) req Nothing+  result <- I.createSession ccManager (I.hostWithScheme _client) ccPort req Nothing   case result of     Just _ -> return ()     Nothing -> assertFailure "testCreateSession: No session was created"  testGetSessionInfo :: TestTree testGetSessionInfo = testCase "testGetSessionInfo" $ do-  man <- manager+  _client@ConsulClient{..} <- client   let req = SessionRequest Nothing (Just "testGetSessionInfo") Nothing ["serfHealth"] (Just Release) (Just "30s")-  result <- I.createSession man "localhost" (PortNum 8500) req Nothing+  result <- I.createSession ccManager (I.hostWithScheme _client) ccPort req Nothing   case result of     Just x -> do-      x1 <- I.getSessionInfo man "localhost" (PortNum 8500) (sId x) Nothing+      x1 <- I.getSessionInfo ccManager (I.hostWithScheme _client) ccPort (sId x) Nothing       case x1 of         Just _ -> return ()         Nothing -> assertFailure "testGetSessionInfo: Session Info was not returned"@@ -127,12 +157,12 @@  testRenewSession :: TestTree testRenewSession = testCase "testRenewSession" $ do-  man <- manager+  _client@ConsulClient{..} <- client   let req = SessionRequest Nothing (Just "testRenewSession") Nothing ["serfHealth"] (Just Release) (Just "30s")-  result <- I.createSession man "localhost" (PortNum 8500) req Nothing+  result <- I.createSession ccManager (I.hostWithScheme _client) ccPort req Nothing   case result of     Just x -> do-      x1 <- I.renewSession man "localhost" (PortNum 8500) x Nothing+      x1 <- I.renewSession ccManager (I.hostWithScheme _client) ccPort x Nothing       case x1 of         True -> return ()         False -> assertFailure "testRenewSession: Session was not renewed"@@ -140,13 +170,13 @@  testDestroySession :: TestTree testDestroySession = testCase "testDestroySession" $ do-  man <- manager+  _client@ConsulClient{..} <- client   let req = SessionRequest Nothing (Just "testDestroySession") Nothing ["serfHealth"] (Just Release) (Just "30s")-  result <- I.createSession man "localhost" (PortNum 8500) req Nothing+  result <- I.createSession ccManager (I.hostWithScheme _client) ccPort req Nothing   case result of     Just x -> do-      _ <- I.destroySession man "localhost" (PortNum 8500) x Nothing-      x1 <- I.getSessionInfo man "localhost" (PortNum 8500) (sId x) Nothing+      _ <- I.destroySession ccManager (I.hostWithScheme _client) ccPort x Nothing+      x1 <- I.getSessionInfo ccManager (I.hostWithScheme _client) ccPort (sId x) Nothing       assertEqual "testDestroySession: Session info was returned after destruction" Nothing x1     Nothing -> assertFailure "testDestroySession: No session was created" @@ -156,13 +186,13 @@ {- Managed Session -} testCreateManagedSession :: TestTree testCreateManagedSession = testCase "testCreateManagedSession" $ do-  client <- initializeConsulClient "localhost" (PortNum 8500) Nothing+  client <- initializeConsulClient "localhost" 8500 Nothing   x <- createManagedSession client (Just "testCreateManagedSession") "60s"   assertEqual "testCreateManagedSession: Session not created" True (isJust x)  testSessionMaintained :: TestTree testSessionMaintained = testCase "testSessionMaintained" $ do-  client <- initializeConsulClient "localhost" (PortNum 8500) Nothing+  client <- initializeConsulClient "localhost" 8500 Nothing   x <- createManagedSession client (Just "testCreateManagedSession") "10s"   assertEqual "testSessionMaintained: Session not created" True (isJust x)   let (Just foo) = x@@ -172,18 +202,17 @@  testWithSessionCancel :: TestTree testWithSessionCancel = testCase "testWithSessionCancel" $ do-  man <- manager-  client <- initializeConsulClient "localhost" (PortNum 8500) Nothing+  client@ConsulClient{..} <- initializeConsulClient "localhost" 8500 Nothing   let req = SessionRequest Nothing (Just "testWithSessionCancel") Nothing ["serfHealth"] (Just Release) (Just "10s")-  result <- I.createSession man "localhost" (PortNum 8500) req Nothing+  result <- I.createSession ccManager (I.hostWithScheme client) ccPort req Nothing   case result of     Just x -> do-      x1 <- withSession client x (\ y -> action y man ) cancelAction+      x1 <- withSession client x (\ y -> action y client ) cancelAction       assertEqual "testWithSessionCancel: Incorrect value" "Canceled" x1     Nothing -> assertFailure "testWithSessionCancel: No session was created"   where-    action x man = do-      I.destroySession man "localhost" (PortNum 8500) x Nothing+    action x client@ConsulClient{..} = do+      I.destroySession ccManager (I.hostWithScheme client) ccPort x Nothing       threadDelay (30 * 1000000)       return ("NotCanceled" :: Text)     cancelAction = return ("Canceled" :: Text)@@ -196,7 +225,7 @@ agentTests = testGroup "Agent Tests" [testGetSelf,testRegisterService]  allTests :: TestTree-allTests = testGroup "All Tests" [testInternalSession, internalKVTests, managedSessionTests, agentTests]+allTests = testGroup "All Tests" [testInternalSession, internalKVTests, managedSessionTests, agentTests,testHealth]  main :: IO () main = defaultMain allTests