git.iko.soy/typeable/bloodhound
on master help sign in
WIP testing restore API
commit051a15ec053e3065346f36e9d5e13a975eb92acd authorMichael Xavier <michael@michaelxavier.net> dateWed 20 Jul 2016, 16:47 (10 years ago) parent841dfa7
3 files changed+152−10
src/Database/Bloodhound/Client.hs+38−2 src/Database/Bloodhound/Types.hs+111−8 tests/tests.hs+3
src/Database/Bloodhound/Client.hs+38−2
@@ -66,6 +66,7 @@ module Database.Bloodhound.Client
6666 , createSnapshot
6767 , getSnapshots
6868 , deleteSnapshot
69+ , restoreSnapshot
6970 , encodeBulkOperations
7071 , encodeBulkOperation
7172 -- * Authentication
@@ -361,7 +362,11 @@ createSnapshot (SnapshotRepoName repoName)
361362 , Just ("ignore_global_state" .= snapIncludeGlobalState)
362363 , Just ("partial" .= snapPartial)
363364 ]
364− renderIndices (i :| is) = T.intercalate "," (renderIndex <$> (i:is))
365+
366+
367+renderIndices :: NonEmpty IndexName -> Text
368+renderIndices (i :| is) = T.intercalate "," (renderIndex <$> (i:is))
369+ where
365370 renderIndex (IndexName n) = n
366371
367372
@@ -400,6 +405,37 @@ deleteSnapshot (SnapshotRepoName repoName) (SnapshotName snapName) =
400405 url = joinPath ["_snapshot", repoName, snapName]
401406
402407
408+-- | Restore a snapshot to the cluster See
409+-- <https://www.elastic.co/guide/en/elasticsearch/reference/1.7/modules-snapshots.html#_restore>
410+-- for more details.
411+restoreSnapshot
412+ :: MonadBH m
413+ => SnapshotRepoName
414+ -> SnapshotName
415+ -> SnapshotRestoreSettings
416+ -- ^ Start with 'defaultSnapshotRestoreSettings' and customize
417+ -- from there for reasonable defaults.
418+ -> m Reply
419+restoreSnapshot (SnapshotRepoName repoName)
420+ (SnapshotName snapName)
421+ SnapshotRestoreSettings {..} = bindM2 put url (return (Just body))
422+ where
423+ url = addQuery params <$> joinPath ["_snapshot", repoName, snapName, "_restore"]
424+ params = [("wait_for_completion", Just (boolQP snapRestoreWaitForCompletion))]
425+ body = encode (object prs)
426+ prs = catMaybes [ ("indices" .=) . renderIndices <$> snapRestoreIndices
427+ , Just ("ignore_unavailable" .= snapRestoreIgnoreUnavailable)
428+ , Just ("include_global_state" .= snapRestoreIncludeGlobalState)
429+ , ("rename_pattern" .=) <$> snapRestoreRenamePattern
430+ , ("rename_replacement" .=) . renderTokens <$> snapRestoreRenameReplacement
431+ , Just ("include_aliases" .= snapRestoreIncludeAliases)
432+ ]
433+ renderTokens (t :| ts) = mconcat (renderToken <$> (t:ts))
434+ renderToken (RRTLit t) = t
435+ renderToken RRSubWholeMatch = "$0"
436+ renderToken (RRSubGroup g) = T.pack (show (rrGroupRefNum g))
437+
438+
403439-- | 'createIndex' will create an index given a 'Server', 'IndexSettings', and an 'IndexName'.
404440--
405441-- >>> response <- runBH' $ createIndex defaultIndexSettings (IndexName "didimakeanindex")
@@ -484,7 +520,7 @@ optimizeIndex ixs IndexOptimizationSettings {..} =
484520
485521-------------------------------------------------------------------------------
486522indexSelectionName :: IndexSelection -> Text
487−indexSelectionName (IndexList names) = T.intercalate "," [n | IndexName n <- toList names]
523+indexSelectionName (IndexList names) = renderIndices names
488524indexSelectionName AllIndexes = "_all"
489525
490526deepMerge :: [Object] -> Object
src/Database/Bloodhound/Types.hs+111−8
@@ -260,6 +260,13 @@ module Database.Bloodhound.Types
260260 , SnapshotInfo(..)
261261 , SnapshotName(..)
262262 , SnapshotState(..)
263+ , SnapshotRestoreSettings(..)
264+ , defaultSnapshotRestoreSettings
265+ , RestoreRenamePattern(..)
266+ , RestoreRenameToken(..)
267+ , RRGroupRefNum
268+ , rrGroupRefNum
269+ , mkRRGroupRefNum
263270
264271 , Aggregation(..)
265272 , Aggregations
@@ -3831,23 +3838,23 @@ instance Exception SnapshotRepoConversionError
38313838
38323839
38333840data SnapshotCreateSettings = SnapshotCreateSettings {
3834− snapWaitForCompletion :: Bool
3841+ snapWaitForCompletion :: Bool
38353842 -- ^ Should the API call return immediately after initializing
3836− -- the snapshot or wait until completed. Note that if this is
3843+ -- the snapshot or wait until completed? Note that if this is
38373844 -- enabled it could wait a long time, so you should adjust your
38383845 -- 'ManagerSettings' accordingly to set long timeouts or
38393846 -- explicitly handle timeouts.
3840− , snapIndices :: Maybe (NonEmpty IndexName)
3847+ , snapIndices :: Maybe (NonEmpty IndexName)
38413848 -- ^ Nothing will snapshot all indices. Just [] is permissable and
38423849 -- will essentially be a no-op snapshot.
3843− , snapIgnoreUnavailable :: Bool
3850+ , snapIgnoreUnavailable :: Bool
38443851 -- ^ If set to True, any matched indices that don't exist will be
38453852 -- ignored. Otherwise it will be an error and fail.
38463853 , snapIncludeGlobalState :: Bool
3847− , snapPartial :: Bool
3854+ , snapPartial :: Bool
38483855 -- ^ If some indices failed to snapshot (e.g. if not all primary
38493856 -- shards are available), should the process proceed?
3850− }
3857+ } deriving (Eq, Generic, Show, Typeable)
38513858
38523859
38533860-- | Reasonable defaults for snapshot creation
@@ -3858,8 +3865,13 @@ data SnapshotCreateSettings = SnapshotCreateSettings {
38583865-- * snapIncludeGlobalState True
38593866-- * snapPartial False
38603867defaultSnapshotCreateSettings :: SnapshotCreateSettings
3861−defaultSnapshotCreateSettings =
3862− SnapshotCreateSettings False Nothing False True False
3868+defaultSnapshotCreateSettings = SnapshotCreateSettings {
3869+ snapWaitForCompletion = False
3870+ , snapIndices = Nothing
3871+ , snapIgnoreUnavailable = False
3872+ , snapIncludeGlobalState = True
3873+ , snapPartial = False
3874+ }
38633875
38643876
38653877data SnapshotSelection = SnapshotList (NonEmpty SnapshotPattern)
@@ -3938,3 +3950,94 @@ instance FromJSON SnapshotState where
39383950
39393951newtype SnapshotName = SnapshotName { snapshotName :: Text }
39403952 deriving (Show, Eq, Ord, Generic, Typeable, ToJSON, FromJSON)
3953+
3954+
3955+data SnapshotRestoreSettings = SnapshotRestoreSettings {
3956+ snapRestoreWaitForCompletion :: Bool
3957+ -- ^ Should the API call return immediately after initializing
3958+ -- the restore or wait until completed? Note that if this is
3959+ -- enabled, it could wait a long time, so you should adjust your
3960+ -- 'ManagerSettings' accordingly to set long timeouts or
3961+ -- explicitly handle timeouts.
3962+ , snapRestoreIndices :: Maybe (NonEmpty IndexName)
3963+ -- ^ Nothing will restore all indices in the snapshot. Just [] is
3964+ -- permissable and will essentially be a no-op restore.
3965+ , snapRestoreIgnoreUnavailable :: Bool
3966+ -- ^ If set to True, any indices that do not exist will be ignored
3967+ -- during snapshot rather than failing the restore.
3968+ , snapRestoreIncludeGlobalState :: Bool
3969+ -- ^ If set to false, will ignore any global state in the snapshot
3970+ -- and will not restore it.
3971+ , snapRestoreRenamePattern :: Maybe RestoreRenamePattern
3972+ -- ^ A regex pattern for matching indices. Used with
3973+ -- 'snapRestoreRenameReplacement', the restore can reference the
3974+ -- matched index and create a new index name upon restore.
3975+ , snapRestoreRenameReplacement :: Maybe (NonEmpty RestoreRenameToken)
3976+ -- ^ Expression of how index renames should be constructed.
3977+ , snapRestorePartial :: Bool
3978+ -- ^ If some indices fail to restore, should the process proceed?
3979+ , snapRestoreIncludeAliases :: Bool
3980+ -- ^ Should the restore also restore the aliases captured in the
3981+ -- snapshot.
3982+ } deriving (Eq, Generic, Show, Typeable)
3983+--TODO: temporary settings changes
3984+
3985+-- | Regex-stype pattern, e.g. "index_(.+)" to match index names
3986+newtype RestoreRenamePattern = RestoreRenamePattern { rrPattern :: Text }
3987+ deriving (Show, Eq, Generic, Typeable, Ord, ToJSON)
3988+
3989+
3990+-- | A single token in a index renaming scheme for a restore. These
3991+-- are concatenated into a string before being sent to
3992+-- ElasticSearch. Check out these Java
3993+-- <https://docs.oracle.com/javase/7/docs/api/java/util/regex/Matcher.html
3994+-- docs> to find out more if you're into that sort of thing.
3995+data RestoreRenameToken = RRTLit Text
3996+ -- ^ Just a literal string of characters
3997+ | RRSubWholeMatch
3998+ -- ^ Equivalent to $0. The entire matched pattern, not any subgroup
3999+ | RRSubGroup RRGroupRefNum
4000+ -- ^ A specific reference to a group number
4001+ deriving (Show, Eq, Generic, Typeable)
4002+
4003+
4004+-- | A group number for regex matching. Only values from 1-9 are
4005+-- supported. Construct with mkRRGroupRefNum
4006+newtype RRGroupRefNum = RRGroupRefNum { rrGroupRefNum :: Int }
4007+ deriving (Show, Eq, Generic, Typeable, Ord)
4008+
4009+instance Bounded RRGroupRefNum where
4010+ minBound = RRGroupRefNum 1
4011+ maxBound = RRGroupRefNum 9
4012+
4013+
4014+
4015+-- | Only allows valid group number references (0-9).
4016+mkRRGroupRefNum :: Int -> Maybe RRGroupRefNum
4017+mkRRGroupRefNum i
4018+ | i >= (rrGroupRefNum minBound) && i <= (rrGroupRefNum maxBound) =
4019+ Just $ RRGroupRefNum i
4020+ | otherwise = Nothing
4021+
4022+
4023+-- | Reasonable defaults for snapshot restores
4024+--
4025+-- * snapRestoreWaitForCompletion False
4026+-- * snapRestoreIndices Nothing
4027+-- * snapRestoreIgnoreUnavailable False
4028+-- * snapRestoreIncludeGlobalState True
4029+-- * snapRestoreRenamePattern Nothing
4030+-- * snapRestoreRenameReplacement Nothing
4031+-- * snapRestorePartial False
4032+-- * snapRestoreIncludeAliases True
4033+defaultSnapshotRestoreSettings :: SnapshotRestoreSettings
4034+defaultSnapshotRestoreSettings = SnapshotRestoreSettings {
4035+ snapRestoreWaitForCompletion = False
4036+ , snapRestoreIndices = Nothing
4037+ , snapRestoreIgnoreUnavailable = False
4038+ , snapRestoreIncludeGlobalState = True
4039+ , snapRestoreRenamePattern = Nothing
4040+ , snapRestoreRenameReplacement = Nothing
4041+ , snapRestorePartial = False
4042+ , snapRestoreIncludeAliases = True
4043+ }
tests/tests.hs+3
@@ -1487,6 +1487,9 @@ main = hspec $ do
14871487 Right snaps -> expectationFailure ("Expected 1 snapshot but got" <> show (length snaps))
14881488 Left e -> expectationFailure (show e)
14891489
1490+ describe "snapshot restore" $ do
1491+ it "can restore a snapshot that we create" pending
1492+
14901493 describe "Enum DocVersion" $ do
14911494 it "follows the laws of Enum, Bounded" $ do
14921495 evaluate (succ maxBound :: DocVersion) `shouldThrow` anyErrorCall