@@ -148,6 +148,8 @@ module Database.Bloodhound.Types
148148 , Script(..)
149149 , IndexName(..)
150150 , IndexSelection(..)
151+ , NodeSelection(..)
152+ , NodeSelector(..)
151153 , IndexOptimizationSettings(..)
152154 , defaultIndexOptimizationSettings
153155 , TemplateName(..)
@@ -338,6 +340,7 @@ module Database.Bloodhound.Types
338340 ) where
339341
340342import Control.Applicative as A
343+import Control.Arrow (first)
341344import Control.Monad.Catch
342345import Control.Monad.Except
343346import Control.Monad.Reader
@@ -898,6 +901,25 @@ newtype IndexName = IndexName Text deriving (Eq, Generic, Read, Show, ToJSON, Fr
898901data IndexSelection = IndexList (NonEmpty IndexName)
899902 | AllIndexes deriving (Eq, Generic, Show, Typeable)
900903
904+{-| 'NodeSelection' is used for most cluster APIs. See <https://www.elastic.co/guide/en/elasticsearch/reference/current/cluster.html#cluster-nodes here> for more details.
905+-}
906+data NodeSelection = LocalNode
907+ -- ^ Whatever node receives this request
908+ | NodeList (NonEmpty NodeSelector)
909+ | AllNodes deriving (Eq, Generic, Show, Typeable)
910+
911+
912+-- | An exact match or pattern to identify a node. Note that All of
913+-- these options support wildcarding, so your node name, server, attr
914+-- name can all contain * characters to be a fuzzy match.
915+data NodeSelector = NodeByName NodeName
916+ | NodeByFullNodeId FullNodeId
917+ | NodeByHost Server
918+ -- ^ e.g. 10.0.0.1 or even 10.0.0.*
919+ | NodeByAttribute NodeAttrName Text
920+ -- ^ NodeAttrName can be a pattern, e.g. rack*. The value can too.
921+ deriving (Eq, Generic, Show, Typeable)
922+
901923{-| 'TemplateName' is used to describe which template to query/create/delete
902924-}
903925newtype TemplateName = TemplateName Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
@@ -3833,9 +3855,9 @@ newtype PluginName = PluginName { pluginName :: Text }
38333855 deriving (Eq, Ord, Generic, Show, Typeable, FromJSON)
38343856
38353857data NodeInfo = NodeInfo {
3836− nodeInfoHTTPAddress :: EsAddress --TODO: better name
3858+ nodeInfoHTTPAddress :: EsAddress
38373859 , nodeInfoBuild :: BuildHash
3838− , nodeInfoESVersion :: VersionNumber --TODO: distribution provides this
3860+ , nodeInfoESVersion :: VersionNumber
38393861 , nodeInfoIP :: Server
38403862 , nodeInfoHost :: Server
38413863 , nodeInfoTransportAddress :: EsAddress
@@ -3849,6 +3871,9 @@ data NodeInfo = NodeInfo {
38493871 , nodeInfoJVM :: NodeJVMInfo
38503872 , nodeInfoProcess :: NodeProcessInfo
38513873 , nodeInfoOS :: NodeOSInfo
3874+ , nodeInfoSettings :: Object
3875+ -- ^ The members of the settings objects are not consistent,
3876+ -- dependent on plugins, etc.
38523877 } deriving (Eq, Show, Generic, Typeable)
38533878
38543879data NodePluginInfo = NodePluginInfo {
@@ -3872,8 +3897,8 @@ data NodeTransportInfo = NodeTransportInfo {
38723897 } deriving (Eq, Show, Generic, Typeable)
38733898
38743899data BoundTransportAddress = BoundTransportAddress {
3875− publicAddress :: EsAddress
3876− , boundAddress :: EsAddress
3900+ publishAddress :: EsAddress
3901+ , boundAddress :: EsAddress
38773902 } deriving (Eq, Show, Generic, Typeable)
38783903
38793904data NodeNetworkInfo = NodeNetworkInfo {
@@ -3921,7 +3946,7 @@ data NodeThreadPoolInfo = NodeThreadPoolInfo {
39213946 , nodeThreadPoolType :: ThreadPoolType
39223947 } deriving (Eq, Show, Generic, Typeable)
39233948
3924−data ThreadPoolSize = ThreadPoolLimited Int
3949+data ThreadPoolSize = ThreadPoolBounded Int
39253950 | ThreadPoolUnbounded
39263951 deriving (Eq, Show, Generic, Typeable)
39273952
@@ -3943,6 +3968,9 @@ data NodeJVMInfo = NodeJVMInfo {
39433968 , nodeJVMPID :: PID
39443969 } deriving (Eq, Show, Generic, Typeable)
39453970
3971+-- | Handles quirks in the way JVM versions are rendered (1.7.0_101 -> 1.7.0.101)
3972+newtype JVMVersion = JVMVersion { unJVMVersion :: VersionNumber }
3973+
39463974data JVMMemoryInfo = JVMMemoryInfo {
39473975 jvmMemoryInfoDirectMax :: Bytes
39483976 , jvmMemoryInfoNonHeapMax :: Bytes
@@ -4319,3 +4347,208 @@ instance ToJSON RestoreIndexSettings where
43194347 toJSON RestoreIndexSettings {..} = object prs
43204348 where
43214349 prs = catMaybes [("index.number_of_replicas" .=) <$> restoreOverrideReplicas]
4350+
4351+
4352+instance FromJSON NodesInfo where
4353+ parseJSON = withObject "NodesInfo" parse
4354+ where
4355+ parse o = do
4356+ nodes <- o .: "nodes"
4357+ infos <- forM (HM.toList nodes) $ \(fullNID, v) -> do
4358+ node <- parseJSON v
4359+ parseNodeInfo (FullNodeId fullNID) node
4360+ cn <- o .: "cluster_name"
4361+ return (NodesInfo infos cn)
4362+
4363+
4364+parseNodeInfo :: FullNodeId -> Object -> Parser NodeInfo
4365+parseNodeInfo nid o =
4366+ NodeInfo <$> o .: "http_address"
4367+ <*> o .: "build"
4368+ <*> o .: "version"
4369+ <*> o .: "ip"
4370+ <*> o .: "host"
4371+ <*> o .: "transport_address"
4372+ <*> o .: "name"
4373+ <*> pure nid
4374+ <*> o .: "plugins"
4375+ <*> o .: "http"
4376+ <*> o .: "transport"
4377+ <*> o .: "network"
4378+ <*> o .: "thread_pool"
4379+ <*> o .: "jvm"
4380+ <*> o .: "process"
4381+ <*> o .: "os"
4382+ <*> o .: "settings"
4383+
4384+instance FromJSON NodePluginInfo where
4385+ parseJSON = withObject "NodePluginInfo" parse
4386+ where
4387+ parse o = NodePluginInfo <$> o .: "site"
4388+ <*> o .: "jvm"
4389+ <*> o .: "description"
4390+ <*> o .: "version"
4391+ <*> o .: "name"
4392+
4393+instance FromJSON NodeHTTPInfo where
4394+ parseJSON = withObject "NodeHTTPInfo" parse
4395+ where
4396+ parse o = NodeHTTPInfo <$> o .: "max_content_length_in_bytes"
4397+ <*> parseJSON (Object o)
4398+
4399+instance FromJSON BoundTransportAddress where
4400+ parseJSON = withObject "BoundTransportAddress" parse
4401+ where
4402+ parse o = BoundTransportAddress <$> o .: "publish_address"
4403+ <*> o .: "bound_address"
4404+
4405+instance FromJSON NodeOSInfo where
4406+ parseJSON = withObject "NodeOSInfo" parse
4407+ where
4408+ parse o = do
4409+ swap <- o .: "swap"
4410+ mem <- o .: "mem"
4411+ NodeOSInfo <$> swap .: "total_in_bytes"
4412+ <*> mem .: "total_in_bytes"
4413+ <*> o .: "cpu"
4414+ <*> o .: "available_processors"
4415+ <*> (unMS <$> o .: "refresh_interval_in_millis")
4416+
4417+
4418+instance FromJSON CPUInfo where
4419+ parseJSON = withObject "CPUInfo" parse
4420+ where
4421+ parse o = CPUInfo <$> o .: "cache_size_in_bytes"
4422+ <*> o .: "cores_per_socket"
4423+ <*> o .: "total_sockets"
4424+ <*> o .: "total_cores"
4425+ <*> o .: "mhz"
4426+ <*> o .: "model"
4427+ <*> o .: "vendor"
4428+
4429+instance FromJSON NodeProcessInfo where
4430+ parseJSON = withObject "NodeProcessInfo" parse
4431+ where
4432+ parse o = NodeProcessInfo <$> o .: "mlockall"
4433+ <*> o .: "max_file_descriptors"
4434+ <*> o .: "id"
4435+ <*> (unMS <$> o .: "refresh_interval_in_millis")
4436+
4437+instance FromJSON NodeJVMInfo where
4438+ parseJSON = withObject "NodeJVMInfo" parse
4439+ where
4440+ parse o = NodeJVMInfo <$> o .: "memory_pools"
4441+ <*> o .: "gc_collectors"
4442+ <*> o .: "mem"
4443+ <*> (posixMS <$> o .: "start_time_in_millis")
4444+ <*> o .: "vm_vendor"
4445+ <*> o .: "vm_version"
4446+ <*> o .: "vm_name"
4447+ <*> (unJVMVersion <$> o .: "version")
4448+ <*> o .: "pid"
4449+
4450+instance FromJSON JVMVersion where
4451+ parseJSON (String t) =
4452+ JVMVersion <$> parseJSON (String (T.replace "_" "." t))
4453+ parseJSON v = JVMVersion <$> parseJSON v
4454+
4455+instance FromJSON JVMMemoryInfo where
4456+ parseJSON = withObject "JVMMemoryInfo" parse
4457+ where
4458+ parse o = JVMMemoryInfo <$> o .: "direct_max_in_bytes"
4459+ <*> o .: "non_heap_max_in_bytes"
4460+ <*> o .: "non_heap_init_in_bytes"
4461+ <*> o .: "heap_max_in_bytes"
4462+ <*> o .: "heap_init_in_bytes"
4463+
4464+instance FromJSON NodeThreadPoolsInfo where
4465+ parseJSON = withObject "NodeThreadPoolsInfo" parse
4466+ where
4467+ parse o = NodeThreadPoolsInfo <$> o .: "refresh"
4468+ <*> o .: "management"
4469+ <*> o .: "percolate"
4470+ <*> o .: "listener"
4471+ <*> o .: "fetch_shard_started"
4472+ <*> o .: "search"
4473+ <*> o .: "flush"
4474+ <*> o .: "warmer"
4475+ <*> o .: "optimize"
4476+ <*> o .: "bulk"
4477+ <*> o .: "suggest"
4478+ <*> o .: "merge"
4479+ <*> o .: "snapshot"
4480+ <*> o .: "get"
4481+ <*> o .: "fetch_shard_store"
4482+ <*> o .: "index"
4483+ <*> o .: "generic"
4484+
4485+instance FromJSON NodeThreadPoolInfo where
4486+ parseJSON = withObject "NodeThreadPoolInfo" parse
4487+ where
4488+ parse o = do
4489+ ka <- maybe (return Nothing) (fmap Just . parseStringInterval) =<< o .:? "keep_alive"
4490+ NodeThreadPoolInfo <$> (parseJSON . unStringlyTypeJSON =<< o .: "queue_size")
4491+ <*> pure ka
4492+ <*> o .:? "min"
4493+ <*> o .:? "max"
4494+ <*> o .: "type"
4495+
4496+parseStringInterval :: (Monad m) => String -> m NominalDiffTime
4497+parseStringInterval s = case span isNumber s of
4498+ ("", _) -> fail "Invalid interval"
4499+ (nS, unitS) -> case (readMay nS, readMay unitS) of
4500+ (Just n, Just unit) -> return (fromInteger (n * unitNDT unit))
4501+ (Nothing, _) -> fail "Invalid interval number"
4502+ (_, Nothing) -> fail "Invalid interval unit"
4503+ where
4504+ unitNDT Seconds = 1
4505+ unitNDT Minutes = 60
4506+ unitNDT Hours = 60 * 60
4507+ unitNDT Days = 24 * 60 * 60
4508+ unitNDT Weeks = 7 * 24 * 60 * 60
4509+
4510+instance FromJSON ThreadPoolSize where
4511+ parseJSON v = parseAsNumber v <|> parseAsString v
4512+ where
4513+ parseAsNumber = parseAsInt <=< parseJSON
4514+ parseAsInt (-1) = return ThreadPoolUnbounded
4515+ parseAsInt n
4516+ | n >= 0 = return (ThreadPoolBounded n)
4517+ | otherwise = fail "Thread pool size must be >= -1."
4518+ parseAsString = withText "ThreadPoolSize" $ \t ->
4519+ case first (readMay . T.unpack) (T.span isNumber t) of
4520+ (Just n, "k") -> return (ThreadPoolBounded (n * 1000))
4521+ (Just n, "") -> return (ThreadPoolBounded n)
4522+ _ -> fail ("Invalid thread pool size " <> T.unpack t)
4523+
4524+instance FromJSON ThreadPoolType where
4525+ parseJSON = withText "ThreadPoolType" parse
4526+ where
4527+ parse "scaling" = return ThreadPoolScaling
4528+ parse "fixed" = return ThreadPoolFixed
4529+ parse "cached" = return ThreadPoolCached
4530+ parse e = fail ("Unexpected thread pool type" <> T.unpack e)
4531+
4532+instance FromJSON NodeTransportInfo where
4533+ parseJSON = withObject "NodeTransportInfo" parse
4534+ where
4535+ parse o = NodeTransportInfo <$> (parseProfiles =<< o .: "profiles")
4536+ <*> parseJSON (Object o)
4537+ parseProfiles (Object o) | HM.null o = return []
4538+ parseProfiles v@(Array _) = parseJSON v
4539+ parseProfiles Null = return []
4540+ parseProfiles _ = fail "Could not parse profiles"
4541+
4542+instance FromJSON NodeNetworkInfo where
4543+ parseJSON = withObject "NodeNetworkInfo" parse
4544+ where
4545+ parse o = NodeNetworkInfo <$> o .: "primary_interface"
4546+ <*> (unMS <$> o .: "refresh_interval_in_millis")
4547+
4548+
4549+instance FromJSON NodeNetworkInterface where
4550+ parseJSON = withObject "NodeNetworkInterface" parse
4551+ where
4552+ parse o = NodeNetworkInterface <$> o .: "mac_address"
4553+ <*> o .: "name"
4554+ <*> o .: "address"