{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE StrictData #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# OPTIONS_GHC -fno-warn-unused-binds #-}
{-# OPTIONS_GHC -fno-warn-unused-imports #-}
{-# OPTIONS_GHC -fno-warn-unused-matches #-}

-- Derived from AWS service descriptions, licensed under Apache 2.0.

-- |
-- Module      : Amazonka.ElastiCache.TestFailover
-- Copyright   : (c) 2013-2023 Brendan Hay
-- License     : Mozilla Public License, v. 2.0.
-- Maintainer  : Brendan Hay
-- Stability   : auto-generated
-- Portability : non-portable (GHC extensions)
--
-- Represents the input of a @TestFailover@ operation which test automatic
-- failover on a specified node group (called shard in the console) in a
-- replication group (called cluster in the console).
--
-- This API is designed for testing the behavior of your application in
-- case of ElastiCache failover. It is not designed to be an operational
-- tool for initiating a failover to overcome a problem you may have with
-- the cluster. Moreover, in certain conditions such as large-scale
-- operational events, Amazon may block this API.
--
-- __Note the following__
--
-- -   A customer can use this operation to test automatic failover on up
--     to 5 shards (called node groups in the ElastiCache API and Amazon
--     CLI) in any rolling 24-hour period.
--
-- -   If calling this operation on shards in different clusters (called
--     replication groups in the API and CLI), the calls can be made
--     concurrently.
--
-- -   If calling this operation multiple times on different shards in the
--     same Redis (cluster mode enabled) replication group, the first node
--     replacement must complete before a subsequent call can be made.
--
-- -   To determine whether the node replacement is complete you can check
--     Events using the Amazon ElastiCache console, the Amazon CLI, or the
--     ElastiCache API. Look for the following automatic failover related
--     events, listed here in order of occurrance:
--
--     1.  Replication group message:
--         @Test Failover API called for node group \<node-group-id>@
--
--     2.  Cache cluster message:
--         @Failover from primary node \<primary-node-id> to replica node \<node-id> completed@
--
--     3.  Replication group message:
--         @Failover from primary node \<primary-node-id> to replica node \<node-id> completed@
--
--     4.  Cache cluster message: @Recovering cache nodes \<node-id>@
--
--     5.  Cache cluster message:
--         @Finished recovery for cache nodes \<node-id>@
--
--     For more information see:
--
--     -   <https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/ECEvents.Viewing.html Viewing ElastiCache Events>
--         in the /ElastiCache User Guide/
--
--     -   <https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DescribeEvents.html DescribeEvents>
--         in the ElastiCache API Reference
--
-- Also see,
-- <https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/AutoFailover.html#auto-failover-test Testing Multi-AZ>
-- in the /ElastiCache User Guide/.
module Amazonka.ElastiCache.TestFailover
  ( -- * Creating a Request
    TestFailover (..),
    newTestFailover,

    -- * Request Lenses
    testFailover_replicationGroupId,
    testFailover_nodeGroupId,

    -- * Destructuring the Response
    TestFailoverResponse (..),
    newTestFailoverResponse,

    -- * Response Lenses
    testFailoverResponse_replicationGroup,
    testFailoverResponse_httpStatus,
  )
where

import qualified Amazonka.Core as Core
import qualified Amazonka.Core.Lens.Internal as Lens
import qualified Amazonka.Data as Data
import Amazonka.ElastiCache.Types
import qualified Amazonka.Prelude as Prelude
import qualified Amazonka.Request as Request
import qualified Amazonka.Response as Response

-- | /See:/ 'newTestFailover' smart constructor.
data TestFailover = TestFailover'
  { -- | The name of the replication group (console: cluster) whose automatic
    -- failover is being tested by this operation.
    TestFailover -> Text
replicationGroupId :: Prelude.Text,
    -- | The name of the node group (called shard in the console) in this
    -- replication group on which automatic failover is to be tested. You may
    -- test automatic failover on up to 5 node groups in any rolling 24-hour
    -- period.
    TestFailover -> Text
nodeGroupId :: Prelude.Text
  }
  deriving (TestFailover -> TestFailover -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TestFailover -> TestFailover -> Bool
$c/= :: TestFailover -> TestFailover -> Bool
== :: TestFailover -> TestFailover -> Bool
$c== :: TestFailover -> TestFailover -> Bool
Prelude.Eq, ReadPrec [TestFailover]
ReadPrec TestFailover
Int -> ReadS TestFailover
ReadS [TestFailover]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [TestFailover]
$creadListPrec :: ReadPrec [TestFailover]
readPrec :: ReadPrec TestFailover
$creadPrec :: ReadPrec TestFailover
readList :: ReadS [TestFailover]
$creadList :: ReadS [TestFailover]
readsPrec :: Int -> ReadS TestFailover
$creadsPrec :: Int -> ReadS TestFailover
Prelude.Read, Int -> TestFailover -> ShowS
[TestFailover] -> ShowS
TestFailover -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TestFailover] -> ShowS
$cshowList :: [TestFailover] -> ShowS
show :: TestFailover -> String
$cshow :: TestFailover -> String
showsPrec :: Int -> TestFailover -> ShowS
$cshowsPrec :: Int -> TestFailover -> ShowS
Prelude.Show, forall x. Rep TestFailover x -> TestFailover
forall x. TestFailover -> Rep TestFailover x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep TestFailover x -> TestFailover
$cfrom :: forall x. TestFailover -> Rep TestFailover x
Prelude.Generic)

-- |
-- Create a value of 'TestFailover' with all optional fields omitted.
--
-- Use <https://hackage.haskell.org/package/generic-lens generic-lens> or <https://hackage.haskell.org/package/optics optics> to modify other optional fields.
--
-- The following record fields are available, with the corresponding lenses provided
-- for backwards compatibility:
--
-- 'replicationGroupId', 'testFailover_replicationGroupId' - The name of the replication group (console: cluster) whose automatic
-- failover is being tested by this operation.
--
-- 'nodeGroupId', 'testFailover_nodeGroupId' - The name of the node group (called shard in the console) in this
-- replication group on which automatic failover is to be tested. You may
-- test automatic failover on up to 5 node groups in any rolling 24-hour
-- period.
newTestFailover ::
  -- | 'replicationGroupId'
  Prelude.Text ->
  -- | 'nodeGroupId'
  Prelude.Text ->
  TestFailover
newTestFailover :: Text -> Text -> TestFailover
newTestFailover Text
pReplicationGroupId_ Text
pNodeGroupId_ =
  TestFailover'
    { $sel:replicationGroupId:TestFailover' :: Text
replicationGroupId =
        Text
pReplicationGroupId_,
      $sel:nodeGroupId:TestFailover' :: Text
nodeGroupId = Text
pNodeGroupId_
    }

-- | The name of the replication group (console: cluster) whose automatic
-- failover is being tested by this operation.
testFailover_replicationGroupId :: Lens.Lens' TestFailover Prelude.Text
testFailover_replicationGroupId :: Lens' TestFailover Text
testFailover_replicationGroupId = forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
Lens.lens (\TestFailover' {Text
replicationGroupId :: Text
$sel:replicationGroupId:TestFailover' :: TestFailover -> Text
replicationGroupId} -> Text
replicationGroupId) (\s :: TestFailover
s@TestFailover' {} Text
a -> TestFailover
s {$sel:replicationGroupId:TestFailover' :: Text
replicationGroupId = Text
a} :: TestFailover)

-- | The name of the node group (called shard in the console) in this
-- replication group on which automatic failover is to be tested. You may
-- test automatic failover on up to 5 node groups in any rolling 24-hour
-- period.
testFailover_nodeGroupId :: Lens.Lens' TestFailover Prelude.Text
testFailover_nodeGroupId :: Lens' TestFailover Text
testFailover_nodeGroupId = forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
Lens.lens (\TestFailover' {Text
nodeGroupId :: Text
$sel:nodeGroupId:TestFailover' :: TestFailover -> Text
nodeGroupId} -> Text
nodeGroupId) (\s :: TestFailover
s@TestFailover' {} Text
a -> TestFailover
s {$sel:nodeGroupId:TestFailover' :: Text
nodeGroupId = Text
a} :: TestFailover)

instance Core.AWSRequest TestFailover where
  type AWSResponse TestFailover = TestFailoverResponse
  request :: (Service -> Service) -> TestFailover -> Request TestFailover
request Service -> Service
overrides =
    forall a. ToRequest a => Service -> a -> Request a
Request.postQuery (Service -> Service
overrides Service
defaultService)
  response :: forall (m :: * -> *).
MonadResource m =>
(ByteStringLazy -> IO ByteStringLazy)
-> Service
-> Proxy TestFailover
-> ClientResponse ClientBody
-> m (Either Error (ClientResponse (AWSResponse TestFailover)))
response =
    forall (m :: * -> *) a.
MonadResource m =>
Text
-> (Int
    -> ResponseHeaders -> [Node] -> Either String (AWSResponse a))
-> (ByteStringLazy -> IO ByteStringLazy)
-> Service
-> Proxy a
-> ClientResponse ClientBody
-> m (Either Error (ClientResponse (AWSResponse a)))
Response.receiveXMLWrapper
      Text
"TestFailoverResult"
      ( \Int
s ResponseHeaders
h [Node]
x ->
          Maybe ReplicationGroup -> Int -> TestFailoverResponse
TestFailoverResponse'
            forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
Prelude.<$> ([Node]
x forall a. FromXML a => [Node] -> Text -> Either String (Maybe a)
Data..@? Text
"ReplicationGroup")
            forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
Prelude.<*> (forall (f :: * -> *) a. Applicative f => a -> f a
Prelude.pure (forall a. Enum a => a -> Int
Prelude.fromEnum Int
s))
      )

instance Prelude.Hashable TestFailover where
  hashWithSalt :: Int -> TestFailover -> Int
hashWithSalt Int
_salt TestFailover' {Text
nodeGroupId :: Text
replicationGroupId :: Text
$sel:nodeGroupId:TestFailover' :: TestFailover -> Text
$sel:replicationGroupId:TestFailover' :: TestFailover -> Text
..} =
    Int
_salt
      forall a. Hashable a => Int -> a -> Int
`Prelude.hashWithSalt` Text
replicationGroupId
      forall a. Hashable a => Int -> a -> Int
`Prelude.hashWithSalt` Text
nodeGroupId

instance Prelude.NFData TestFailover where
  rnf :: TestFailover -> ()
rnf TestFailover' {Text
nodeGroupId :: Text
replicationGroupId :: Text
$sel:nodeGroupId:TestFailover' :: TestFailover -> Text
$sel:replicationGroupId:TestFailover' :: TestFailover -> Text
..} =
    forall a. NFData a => a -> ()
Prelude.rnf Text
replicationGroupId
      seq :: forall a b. a -> b -> b
`Prelude.seq` forall a. NFData a => a -> ()
Prelude.rnf Text
nodeGroupId

instance Data.ToHeaders TestFailover where
  toHeaders :: TestFailover -> ResponseHeaders
toHeaders = forall a b. a -> b -> a
Prelude.const forall a. Monoid a => a
Prelude.mempty

instance Data.ToPath TestFailover where
  toPath :: TestFailover -> ByteString
toPath = forall a b. a -> b -> a
Prelude.const ByteString
"/"

instance Data.ToQuery TestFailover where
  toQuery :: TestFailover -> QueryString
toQuery TestFailover' {Text
nodeGroupId :: Text
replicationGroupId :: Text
$sel:nodeGroupId:TestFailover' :: TestFailover -> Text
$sel:replicationGroupId:TestFailover' :: TestFailover -> Text
..} =
    forall a. Monoid a => [a] -> a
Prelude.mconcat
      [ ByteString
"Action"
          forall a. ToQuery a => ByteString -> a -> QueryString
Data.=: (ByteString
"TestFailover" :: Prelude.ByteString),
        ByteString
"Version"
          forall a. ToQuery a => ByteString -> a -> QueryString
Data.=: (ByteString
"2015-02-02" :: Prelude.ByteString),
        ByteString
"ReplicationGroupId" forall a. ToQuery a => ByteString -> a -> QueryString
Data.=: Text
replicationGroupId,
        ByteString
"NodeGroupId" forall a. ToQuery a => ByteString -> a -> QueryString
Data.=: Text
nodeGroupId
      ]

-- | /See:/ 'newTestFailoverResponse' smart constructor.
data TestFailoverResponse = TestFailoverResponse'
  { TestFailoverResponse -> Maybe ReplicationGroup
replicationGroup :: Prelude.Maybe ReplicationGroup,
    -- | The response's http status code.
    TestFailoverResponse -> Int
httpStatus :: Prelude.Int
  }
  deriving (TestFailoverResponse -> TestFailoverResponse -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TestFailoverResponse -> TestFailoverResponse -> Bool
$c/= :: TestFailoverResponse -> TestFailoverResponse -> Bool
== :: TestFailoverResponse -> TestFailoverResponse -> Bool
$c== :: TestFailoverResponse -> TestFailoverResponse -> Bool
Prelude.Eq, ReadPrec [TestFailoverResponse]
ReadPrec TestFailoverResponse
Int -> ReadS TestFailoverResponse
ReadS [TestFailoverResponse]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [TestFailoverResponse]
$creadListPrec :: ReadPrec [TestFailoverResponse]
readPrec :: ReadPrec TestFailoverResponse
$creadPrec :: ReadPrec TestFailoverResponse
readList :: ReadS [TestFailoverResponse]
$creadList :: ReadS [TestFailoverResponse]
readsPrec :: Int -> ReadS TestFailoverResponse
$creadsPrec :: Int -> ReadS TestFailoverResponse
Prelude.Read, Int -> TestFailoverResponse -> ShowS
[TestFailoverResponse] -> ShowS
TestFailoverResponse -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TestFailoverResponse] -> ShowS
$cshowList :: [TestFailoverResponse] -> ShowS
show :: TestFailoverResponse -> String
$cshow :: TestFailoverResponse -> String
showsPrec :: Int -> TestFailoverResponse -> ShowS
$cshowsPrec :: Int -> TestFailoverResponse -> ShowS
Prelude.Show, forall x. Rep TestFailoverResponse x -> TestFailoverResponse
forall x. TestFailoverResponse -> Rep TestFailoverResponse x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep TestFailoverResponse x -> TestFailoverResponse
$cfrom :: forall x. TestFailoverResponse -> Rep TestFailoverResponse x
Prelude.Generic)

-- |
-- Create a value of 'TestFailoverResponse' with all optional fields omitted.
--
-- Use <https://hackage.haskell.org/package/generic-lens generic-lens> or <https://hackage.haskell.org/package/optics optics> to modify other optional fields.
--
-- The following record fields are available, with the corresponding lenses provided
-- for backwards compatibility:
--
-- 'replicationGroup', 'testFailoverResponse_replicationGroup' - Undocumented member.
--
-- 'httpStatus', 'testFailoverResponse_httpStatus' - The response's http status code.
newTestFailoverResponse ::
  -- | 'httpStatus'
  Prelude.Int ->
  TestFailoverResponse
newTestFailoverResponse :: Int -> TestFailoverResponse
newTestFailoverResponse Int
pHttpStatus_ =
  TestFailoverResponse'
    { $sel:replicationGroup:TestFailoverResponse' :: Maybe ReplicationGroup
replicationGroup =
        forall a. Maybe a
Prelude.Nothing,
      $sel:httpStatus:TestFailoverResponse' :: Int
httpStatus = Int
pHttpStatus_
    }

-- | Undocumented member.
testFailoverResponse_replicationGroup :: Lens.Lens' TestFailoverResponse (Prelude.Maybe ReplicationGroup)
testFailoverResponse_replicationGroup :: Lens' TestFailoverResponse (Maybe ReplicationGroup)
testFailoverResponse_replicationGroup = forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
Lens.lens (\TestFailoverResponse' {Maybe ReplicationGroup
replicationGroup :: Maybe ReplicationGroup
$sel:replicationGroup:TestFailoverResponse' :: TestFailoverResponse -> Maybe ReplicationGroup
replicationGroup} -> Maybe ReplicationGroup
replicationGroup) (\s :: TestFailoverResponse
s@TestFailoverResponse' {} Maybe ReplicationGroup
a -> TestFailoverResponse
s {$sel:replicationGroup:TestFailoverResponse' :: Maybe ReplicationGroup
replicationGroup = Maybe ReplicationGroup
a} :: TestFailoverResponse)

-- | The response's http status code.
testFailoverResponse_httpStatus :: Lens.Lens' TestFailoverResponse Prelude.Int
testFailoverResponse_httpStatus :: Lens' TestFailoverResponse Int
testFailoverResponse_httpStatus = forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
Lens.lens (\TestFailoverResponse' {Int
httpStatus :: Int
$sel:httpStatus:TestFailoverResponse' :: TestFailoverResponse -> Int
httpStatus} -> Int
httpStatus) (\s :: TestFailoverResponse
s@TestFailoverResponse' {} Int
a -> TestFailoverResponse
s {$sel:httpStatus:TestFailoverResponse' :: Int
httpStatus = Int
a} :: TestFailoverResponse)

instance Prelude.NFData TestFailoverResponse where
  rnf :: TestFailoverResponse -> ()
rnf TestFailoverResponse' {Int
Maybe ReplicationGroup
httpStatus :: Int
replicationGroup :: Maybe ReplicationGroup
$sel:httpStatus:TestFailoverResponse' :: TestFailoverResponse -> Int
$sel:replicationGroup:TestFailoverResponse' :: TestFailoverResponse -> Maybe ReplicationGroup
..} =
    forall a. NFData a => a -> ()
Prelude.rnf Maybe ReplicationGroup
replicationGroup
      seq :: forall a b. a -> b -> b
`Prelude.seq` forall a. NFData a => a -> ()
Prelude.rnf Int
httpStatus