git.iko.soy/typeable/bloodhound
on master help sign in
Merge remote-tracking branch 'origin/update-index-settings' into date-range-agg
commit43523a4a2c14103b1d6f286ae206db4505c148e6 authorMichael Xavier <michael@michaelxavier.net> dateSat 14 Nov 2015, 14:16 (11 years ago) parent6a2503f1241ec3
2 files changed+209−2
src/Database/Bloodhound/Client.hs+33−1 src/Database/Bloodhound/Types.hs+176−1
src/Database/Bloodhound/Client.hs+33−1
@@ -24,6 +24,7 @@ module Database.Bloodhound.Client
2424 withBH
2525 , createIndex
2626 , deleteIndex
27+ , updateIndexSettings
2728 , indexExists
2829 , openIndex
2930 , closeIndex
@@ -72,8 +73,9 @@ import Data.Aeson
7273import Data.ByteString.Lazy.Builder
7374import qualified Data.ByteString.Lazy.Char8 as L
7475import Data.Foldable (toList)
76+import qualified Data.HashMap.Strict as HM
7577import Data.Ix
76−import qualified Data.List as LS (filter)
78+import qualified Data.List as LS (filter, foldl')
7779import Data.List.NonEmpty (NonEmpty (..))
7880import Data.Maybe (fromMaybe, isJust)
7981import Data.Monoid
@@ -264,6 +266,7 @@ createIndex indexSettings (IndexName indexName) =
264266 where url = joinPath [indexName]
265267 body = Just $ encode indexSettings
266268
269+
267270-- | 'deleteIndex' will delete an index given a 'Server', and an 'IndexName'.
268271--
269272-- >>> _ <- runBH' $ createIndex defaultIndexSettings (IndexName "didimakeanindex")
@@ -276,6 +279,35 @@ deleteIndex :: MonadBH m => IndexName -> m Reply
276279deleteIndex (IndexName indexName) =
277280 delete =<< joinPath [indexName]
278281
282+-- | 'updateIndexSettings' will apply a non-empty list of setting updates to an index
283+--
284+-- >>> _ <- runBH' $ createIndex defaultIndexSettings (IndexName "unconfiguredindex")
285+-- >>> response <- runBH' $ updateIndexSettings (BlocksWrite False :| []) (IndexName "unconfiguredindex")
286+-- >>> respIsTwoHunna response
287+-- True
288+updateIndexSettings :: MonadBH m => NonEmpty UpdatableIndexSetting -> IndexName -> m Reply
289+updateIndexSettings updates (IndexName indexName) =
290+ bindM2 put url (return body)
291+ where url = joinPath [indexName, "_settings"]
292+ body = Just (encode jsonBody)
293+ jsonBody = Object (deepMerge [u | Object u <- toJSON <$> toList updates])
294+
295+
296+--TODO: This feels a little nicer than returning a reply and coyly
297+--implying that it *should* be an IndexSettingsSummary
298+getIndexSettings :: MonadBH m => IndexName -> m (Either EsError IndexSettingsSummary)
299+getIndexSettings (IndexName indexName) = undefined
300+
301+
302+
303+deepMerge :: [Object] -> Object
304+deepMerge = LS.foldl' go mempty
305+ where go acc = LS.foldl' go' acc . HM.toList
306+ go' acc (k, v) = HM.insertWith merge k v acc
307+ merge (Object a) (Object b) = Object (deepMerge [a, b])
308+ merge _ b = b
309+
310+
279311statusCodeIs :: Int -> Reply -> Bool
280312statusCodeIs n resp = NHTS.statusCode (responseStatus resp) == n
281313
src/Database/Bloodhound/Types.hs+176−1
@@ -58,6 +58,16 @@ module Database.Bloodhound.Types
5858 , Existence(..)
5959 , NullValue(..)
6060 , IndexSettings(..)
61+ , UpdatableIndexSetting(..)
62+ , IndexSettingsSummary(..)
63+ , AllocationPolicy(..)
64+ , ReplicaBounds(..)
65+ , Bytes(..)
66+ , FSType(..)
67+ , InitialShardCount(..)
68+ , NodeAttrFilter(..)
69+ , NodeAttrName(..)
70+ , CompoundFormat(..)
6171 , IndexTemplate(..)
6272 , Server(..)
6373 , Reply
@@ -269,7 +279,7 @@ import Data.Maybe
269279import Data.Text (Text)
270280import qualified Data.Text as T
271281import Data.Time.Calendar
272−import Data.Time.Clock (UTCTime)
282+import Data.Time.Clock (NominalDiffTime, UTCTime)
273283import Data.Time.Clock.POSIX
274284import qualified Data.Traversable as DT
275285import Data.Typeable (Typeable)
@@ -374,6 +384,104 @@ data IndexSettings =
374384defaultIndexSettings :: IndexSettings
375385defaultIndexSettings = IndexSettings (ShardCount 3) (ReplicaCount 2)
376386
387+{-| 'UpdatableIndexSetting' are settings which may be updated after an index is created.
388+
389+ <https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-update-settings.html>
390+-}
391+data UpdatableIndexSetting = NumberOfReplicas ReplicaCount
392+ -- ^ The number of replicas each shard has.
393+ | AutoExpandReplicas ReplicaBounds
394+ | BlocksReadOnly Bool
395+ -- ^ Set to True to have the index read only. False to allow writes and metadata changes.
396+ | BlocksRead Bool
397+ -- ^ Set to True to disable read operations against the index.
398+ | BlocksWrite Bool
399+ -- ^ Set to True to disable write operations against the index.
400+ | BlocksMetaData Bool
401+ -- ^ Set to True to disable metadata operations against the index.
402+ | RefreshInterval NominalDiffTime
403+ -- ^ The async refresh interval of a shard
404+ | IndexConcurrency Int
405+ | FailOnMergeFailure Bool
406+ | TranslogFlushThresholdOps Int
407+ -- ^ When to flush on operations.
408+ | TranslogFlushThresholdSize Bytes
409+ -- ^ When to flush based on translog (bytes) size.
410+ | TranslogFlushThresholdPeriod NominalDiffTime
411+ -- ^ When to flush based on a period of not flushing.
412+ | TranslogDisableFlush Bool
413+ -- ^ Disables flushing. Note, should be set for a short interval and then enabled.
414+ | CacheFilterMaxSize (Maybe Bytes)
415+ -- ^ The maximum size of filter cache (per segment in shard).
416+ | CacheFilterExpire (Maybe NominalDiffTime)
417+ -- ^ The expire after access time for filter cache.
418+ | GatewaySnapshotInterval NominalDiffTime
419+ -- ^ The gateway snapshot interval (only applies to shared gateways).
420+ | RoutingAllocationInclude (NonEmpty NodeAttrFilter)
421+ -- ^ A node matching any rule will be allowed to host shards from the index.
422+ | RoutingAllocationExclude (NonEmpty NodeAttrFilter)
423+ -- ^ A node matching any rule will NOT be allowed to host shards from the index.
424+ | RoutingAllocationRequire (NonEmpty NodeAttrFilter)
425+ -- ^ Only nodes matching all rules will be allowed to host shards from the index.
426+ | RoutingAllocationEnable AllocationPolicy
427+ -- ^ Enables shard allocation for a specific index.
428+ | RoutingAllocationShardsPerNode ShardCount
429+ -- ^ Controls the total number of shards (replicas and primaries) allowed to be allocated on a single node.
430+ | RecoveryInitialShards InitialShardCount
431+ -- ^ When using local gateway a particular shard is recovered only if there can be allocated quorum shards in the cluster.
432+ | GCDeletes NominalDiffTime
433+ | TTLDisablePurge Bool
434+ -- ^ Disables temporarily the purge of expired docs.
435+ | TranslogFSType FSType
436+ | IndexCompoundFormat CompoundFormat
437+ | IndexCompoundOnFlush Bool
438+ | WarmerEnabled Bool
439+ deriving (Eq, Show)
440+
441+data AllocationPolicy = AllocAll
442+ -- ^ Allows shard allocation for all shards.
443+ | AllocPrimaries
444+ -- ^ Allows shard allocation only for primary shards.
445+ | AllocNewPrimaries
446+ -- ^ Allows shard allocation only for primary shards for new indices.
447+ | AllocNone
448+ -- ^ No shard allocation is allowed
449+ deriving (Eq, Show)
450+
451+data ReplicaBounds = ReplicasBounded Int Int
452+ | ReplicasLowerBounded Int
453+ | ReplicasUnbounded
454+ deriving (Eq, Show)
455+
456+newtype Bytes = Bytes Int deriving (Eq, Show, Ord, ToJSON)
457+
458+data FSType = FSSimple
459+ | FSBuffered deriving (Eq, Show, Ord)
460+
461+data InitialShardCount = QuorumShards
462+ | QuorumMinus1Shards
463+ | FullShards
464+ | FullMinus1Shards
465+ | ExplicitShards Int
466+ deriving (Eq, Show)
467+
468+data NodeAttrFilter = NodeAttrFilter { nodeAttrFilterName :: NodeAttrName
469+ , nodeAttrFilterValues :: NonEmpty Text}
470+ deriving (Eq, Show)
471+
472+newtype NodeAttrName = NodeAttrName Text deriving (Eq, Show)
473+
474+data CompoundFormat = CompoundFileFormat Bool
475+ | MergeSegmentVsTotalIndex Double
476+ -- ^ percentage between 0 and 1 where 0 is false, 1 is true
477+ deriving (Eq, Show)
478+
479+newtype NominalDiffTimeJSON = NominalDiffTimeJSON NominalDiffTime
480+
481+data IndexSettingsSummary = IndexSettingsSummary { sSummaryShardCount :: ShardCount
482+ , sSummaryUpdateable :: [UpdatableIndexSetting]}
483+ deriving (Eq, Show)
484+
377485{-| 'Reply' and 'Method' are type synonyms from 'Network.HTTP.Types.Method.Method' -}
378486type Reply = Network.HTTP.Client.Response L.ByteString
379487type Method = NHTM.Method
@@ -2676,6 +2784,73 @@ instance ToJSON IndexSettings where
26762784 ]
26772785 ]
26782786
2787+instance ToJSON UpdatableIndexSetting where
2788+ toJSON (NumberOfReplicas x) = oPath ("index" :| ["number_of_replicas"]) x
2789+ toJSON (AutoExpandReplicas x) = oPath ("index" :| ["auto_expand_replicas"]) x
2790+ toJSON (BlocksReadOnly x) = oPath ("blocks" :| ["read_only"]) x
2791+ toJSON (BlocksRead x) = oPath ("blocks" :| ["read"]) x
2792+ toJSON (BlocksWrite x) = oPath ("blocks" :| ["write"]) x
2793+ toJSON (BlocksMetaData x) = oPath ("blocks" :| ["metadata"]) x
2794+ toJSON (RefreshInterval x) = oPath ("index" :| ["refresh_interval"]) (NominalDiffTimeJSON x)
2795+ toJSON (IndexConcurrency x) = oPath ("index" :| ["concurrency"]) x
2796+ toJSON (FailOnMergeFailure x) = oPath ("index" :| ["fail_on_merge_failure"]) x
2797+ toJSON (TranslogFlushThresholdOps x) = oPath ("index" :| ["translog", "flush_threshold_ops"]) x
2798+ toJSON (TranslogFlushThresholdSize x) = oPath ("index" :| ["translog", "flush_threshold_size"]) x
2799+ toJSON (TranslogFlushThresholdPeriod x) = oPath ("index" :| ["translog", "flush_threshold_period"]) (NominalDiffTimeJSON x)
2800+ toJSON (TranslogDisableFlush x) = oPath ("index" :| ["translog", "disable_flush"]) x
2801+ toJSON (CacheFilterMaxSize x) = oPath ("index" :| ["cache", "filter", "max_size"]) x
2802+ toJSON (CacheFilterExpire x) = oPath ("index" :| ["cache", "filter", "expire"]) (NominalDiffTimeJSON <$> x)
2803+ toJSON (GatewaySnapshotInterval x) = oPath ("index" :| ["gateway", "snapshot_interval"]) (NominalDiffTimeJSON x)
2804+ toJSON (RoutingAllocationInclude fs) = oPath ("index" :| ["routing", "allocation", "include"]) (attrFilterJSON fs)
2805+ toJSON (RoutingAllocationExclude fs) = oPath ("index" :| ["routing", "allocation", "exclude"]) (attrFilterJSON fs)
2806+ toJSON (RoutingAllocationRequire fs) = oPath ("index" :| ["routing", "allocation", "require"]) (attrFilterJSON fs)
2807+ toJSON (RoutingAllocationEnable x) = oPath ("index" :| ["routing", "allocation", "enable"]) x
2808+ toJSON (RoutingAllocationShardsPerNode x) = oPath ("index" :| ["routing", "allocation", "total_shards_per_node"]) x
2809+ toJSON (RecoveryInitialShards x) = oPath ("index" :| ["recovery", "initial_shards"]) x
2810+ toJSON (GCDeletes x) = oPath ("index" :| ["gc_deletes"]) (NominalDiffTimeJSON x)
2811+ toJSON (TTLDisablePurge x) = oPath ("index" :| ["ttl", "disable_purge"]) x
2812+ toJSON (TranslogFSType x) = oPath ("index" :| ["translog", "fs", "type"]) x
2813+ toJSON (IndexCompoundFormat x) = oPath ("index" :| ["compound_format"]) x
2814+ toJSON (IndexCompoundOnFlush x) = oPath ("index" :| ["compound_on_flush"]) x
2815+ toJSON (WarmerEnabled x) = oPath ("index" :| ["warmer", "enabled"]) x
2816+
2817+oPath :: ToJSON a => NonEmpty Text -> a -> Value
2818+oPath (k :| []) v = object [k .= v]
2819+oPath (k:| (h:t)) v = object [k .= oPath (h :| t) v]
2820+
2821+attrFilterJSON :: NonEmpty NodeAttrFilter -> Value
2822+attrFilterJSON fs = object [ n .= T.intercalate "," (toList vs)
2823+ | NodeAttrFilter (NodeAttrName n) vs <- toList fs]
2824+
2825+instance ToJSON ReplicaBounds where
2826+ toJSON (ReplicasBounded a b) = String (showText a <> "-" <> showText b)
2827+ toJSON (ReplicasLowerBounded a) = String (showText a <> "-all")
2828+ toJSON ReplicasUnbounded = Bool False
2829+
2830+instance ToJSON AllocationPolicy where
2831+ toJSON AllocAll = String "all"
2832+ toJSON AllocPrimaries = String "primaries"
2833+ toJSON AllocNewPrimaries = String "new_primaries"
2834+ toJSON AllocNone = String "none"
2835+
2836+instance ToJSON InitialShardCount where
2837+ toJSON QuorumShards = String "quorum"
2838+ toJSON QuorumMinus1Shards = String "quorum-1"
2839+ toJSON FullShards = String "full"
2840+ toJSON FullMinus1Shards = String "full-1"
2841+ toJSON (ExplicitShards x) = toJSON x
2842+
2843+instance ToJSON FSType where
2844+ toJSON FSSimple = "simple"
2845+ toJSON FSBuffered = "buffered"
2846+
2847+instance ToJSON CompoundFormat where
2848+ toJSON (CompoundFileFormat x) = Bool x
2849+ toJSON (MergeSegmentVsTotalIndex x) = toJSON x
2850+
2851+instance ToJSON NominalDiffTimeJSON where
2852+ toJSON (NominalDiffTimeJSON t) = String (showText (round t :: Integer) <> "s")
2853+
26792854instance ToJSON IndexTemplate where
26802855 toJSON (IndexTemplate p s m) = merge
26812856 (object [ "template" .= p