{-# 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.Firehose.PutRecord
-- Copyright   : (c) 2013-2023 Brendan Hay
-- License     : Mozilla Public License, v. 2.0.
-- Maintainer  : Brendan Hay
-- Stability   : auto-generated
-- Portability : non-portable (GHC extensions)
--
-- Writes a single data record into an Amazon Kinesis Data Firehose
-- delivery stream. To write multiple data records into a delivery stream,
-- use PutRecordBatch. Applications using these operations are referred to
-- as producers.
--
-- By default, each delivery stream can take in up to 2,000 transactions
-- per second, 5,000 records per second, or 5 MB per second. If you use
-- PutRecord and PutRecordBatch, the limits are an aggregate across these
-- two operations for each delivery stream. For more information about
-- limits and how to request an increase, see
-- <https://docs.aws.amazon.com/firehose/latest/dev/limits.html Amazon Kinesis Data Firehose Limits>.
--
-- You must specify the name of the delivery stream and the data record
-- when using PutRecord. The data record consists of a data blob that can
-- be up to 1,000 KiB in size, and any kind of data. For example, it can be
-- a segment from a log file, geographic location data, website clickstream
-- data, and so on.
--
-- Kinesis Data Firehose buffers records before delivering them to the
-- destination. To disambiguate the data blobs at the destination, a common
-- solution is to use delimiters in the data, such as a newline (@\\n@) or
-- some other character unique within the data. This allows the consumer
-- application to parse individual data items when reading the data from
-- the destination.
--
-- The @PutRecord@ operation returns a @RecordId@, which is a unique string
-- assigned to each record. Producer applications can use this ID for
-- purposes such as auditability and investigation.
--
-- If the @PutRecord@ operation throws a @ServiceUnavailableException@,
-- back off and retry. If the exception persists, it is possible that the
-- throughput limits have been exceeded for the delivery stream.
--
-- Data records sent to Kinesis Data Firehose are stored for 24 hours from
-- the time they are added to a delivery stream as it tries to send the
-- records to the destination. If the destination is unreachable for more
-- than 24 hours, the data is no longer available.
--
-- Don\'t concatenate two or more base64 strings to form the data fields of
-- your records. Instead, concatenate the raw data, then perform base64
-- encoding.
module Amazonka.Firehose.PutRecord
  ( -- * Creating a Request
    PutRecord (..),
    newPutRecord,

    -- * Request Lenses
    putRecord_deliveryStreamName,
    putRecord_record,

    -- * Destructuring the Response
    PutRecordResponse (..),
    newPutRecordResponse,

    -- * Response Lenses
    putRecordResponse_encrypted,
    putRecordResponse_httpStatus,
    putRecordResponse_recordId,
  )
where

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

-- | /See:/ 'newPutRecord' smart constructor.
data PutRecord = PutRecord'
  { -- | The name of the delivery stream.
    PutRecord -> Text
deliveryStreamName :: Prelude.Text,
    -- | The record.
    PutRecord -> Record
record :: Record
  }
  deriving (PutRecord -> PutRecord -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PutRecord -> PutRecord -> Bool
$c/= :: PutRecord -> PutRecord -> Bool
== :: PutRecord -> PutRecord -> Bool
$c== :: PutRecord -> PutRecord -> Bool
Prelude.Eq, ReadPrec [PutRecord]
ReadPrec PutRecord
Int -> ReadS PutRecord
ReadS [PutRecord]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [PutRecord]
$creadListPrec :: ReadPrec [PutRecord]
readPrec :: ReadPrec PutRecord
$creadPrec :: ReadPrec PutRecord
readList :: ReadS [PutRecord]
$creadList :: ReadS [PutRecord]
readsPrec :: Int -> ReadS PutRecord
$creadsPrec :: Int -> ReadS PutRecord
Prelude.Read, Int -> PutRecord -> ShowS
[PutRecord] -> ShowS
PutRecord -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PutRecord] -> ShowS
$cshowList :: [PutRecord] -> ShowS
show :: PutRecord -> String
$cshow :: PutRecord -> String
showsPrec :: Int -> PutRecord -> ShowS
$cshowsPrec :: Int -> PutRecord -> ShowS
Prelude.Show, forall x. Rep PutRecord x -> PutRecord
forall x. PutRecord -> Rep PutRecord x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep PutRecord x -> PutRecord
$cfrom :: forall x. PutRecord -> Rep PutRecord x
Prelude.Generic)

-- |
-- Create a value of 'PutRecord' 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:
--
-- 'deliveryStreamName', 'putRecord_deliveryStreamName' - The name of the delivery stream.
--
-- 'record', 'putRecord_record' - The record.
newPutRecord ::
  -- | 'deliveryStreamName'
  Prelude.Text ->
  -- | 'record'
  Record ->
  PutRecord
newPutRecord :: Text -> Record -> PutRecord
newPutRecord Text
pDeliveryStreamName_ Record
pRecord_ =
  PutRecord'
    { $sel:deliveryStreamName:PutRecord' :: Text
deliveryStreamName =
        Text
pDeliveryStreamName_,
      $sel:record:PutRecord' :: Record
record = Record
pRecord_
    }

-- | The name of the delivery stream.
putRecord_deliveryStreamName :: Lens.Lens' PutRecord Prelude.Text
putRecord_deliveryStreamName :: Lens' PutRecord Text
putRecord_deliveryStreamName = forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
Lens.lens (\PutRecord' {Text
deliveryStreamName :: Text
$sel:deliveryStreamName:PutRecord' :: PutRecord -> Text
deliveryStreamName} -> Text
deliveryStreamName) (\s :: PutRecord
s@PutRecord' {} Text
a -> PutRecord
s {$sel:deliveryStreamName:PutRecord' :: Text
deliveryStreamName = Text
a} :: PutRecord)

-- | The record.
putRecord_record :: Lens.Lens' PutRecord Record
putRecord_record :: Lens' PutRecord Record
putRecord_record = forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
Lens.lens (\PutRecord' {Record
record :: Record
$sel:record:PutRecord' :: PutRecord -> Record
record} -> Record
record) (\s :: PutRecord
s@PutRecord' {} Record
a -> PutRecord
s {$sel:record:PutRecord' :: Record
record = Record
a} :: PutRecord)

instance Core.AWSRequest PutRecord where
  type AWSResponse PutRecord = PutRecordResponse
  request :: (Service -> Service) -> PutRecord -> Request PutRecord
request Service -> Service
overrides =
    forall a. (ToRequest a, ToJSON a) => Service -> a -> Request a
Request.postJSON (Service -> Service
overrides Service
defaultService)
  response :: forall (m :: * -> *).
MonadResource m =>
(ByteStringLazy -> IO ByteStringLazy)
-> Service
-> Proxy PutRecord
-> ClientResponse ClientBody
-> m (Either Error (ClientResponse (AWSResponse PutRecord)))
response =
    forall (m :: * -> *) a.
MonadResource m =>
(Int -> ResponseHeaders -> Object -> Either String (AWSResponse a))
-> (ByteStringLazy -> IO ByteStringLazy)
-> Service
-> Proxy a
-> ClientResponse ClientBody
-> m (Either Error (ClientResponse (AWSResponse a)))
Response.receiveJSON
      ( \Int
s ResponseHeaders
h Object
x ->
          Maybe Bool -> Int -> Text -> PutRecordResponse
PutRecordResponse'
            forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
Prelude.<$> (Object
x forall a. FromJSON a => Object -> Key -> Either String (Maybe a)
Data..?> Key
"Encrypted")
            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))
            forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
Prelude.<*> (Object
x forall a. FromJSON a => Object -> Key -> Either String a
Data..:> Key
"RecordId")
      )

instance Prelude.Hashable PutRecord where
  hashWithSalt :: Int -> PutRecord -> Int
hashWithSalt Int
_salt PutRecord' {Text
Record
record :: Record
deliveryStreamName :: Text
$sel:record:PutRecord' :: PutRecord -> Record
$sel:deliveryStreamName:PutRecord' :: PutRecord -> Text
..} =
    Int
_salt
      forall a. Hashable a => Int -> a -> Int
`Prelude.hashWithSalt` Text
deliveryStreamName
      forall a. Hashable a => Int -> a -> Int
`Prelude.hashWithSalt` Record
record

instance Prelude.NFData PutRecord where
  rnf :: PutRecord -> ()
rnf PutRecord' {Text
Record
record :: Record
deliveryStreamName :: Text
$sel:record:PutRecord' :: PutRecord -> Record
$sel:deliveryStreamName:PutRecord' :: PutRecord -> Text
..} =
    forall a. NFData a => a -> ()
Prelude.rnf Text
deliveryStreamName
      seq :: forall a b. a -> b -> b
`Prelude.seq` forall a. NFData a => a -> ()
Prelude.rnf Record
record

instance Data.ToHeaders PutRecord where
  toHeaders :: PutRecord -> ResponseHeaders
toHeaders =
    forall a b. a -> b -> a
Prelude.const
      ( forall a. Monoid a => [a] -> a
Prelude.mconcat
          [ HeaderName
"X-Amz-Target"
              forall a. ToHeader a => HeaderName -> a -> ResponseHeaders
Data.=# ( ByteString
"Firehose_20150804.PutRecord" ::
                          Prelude.ByteString
                      ),
            HeaderName
"Content-Type"
              forall a. ToHeader a => HeaderName -> a -> ResponseHeaders
Data.=# ( ByteString
"application/x-amz-json-1.1" ::
                          Prelude.ByteString
                      )
          ]
      )

instance Data.ToJSON PutRecord where
  toJSON :: PutRecord -> Value
toJSON PutRecord' {Text
Record
record :: Record
deliveryStreamName :: Text
$sel:record:PutRecord' :: PutRecord -> Record
$sel:deliveryStreamName:PutRecord' :: PutRecord -> Text
..} =
    [Pair] -> Value
Data.object
      ( forall a. [Maybe a] -> [a]
Prelude.catMaybes
          [ forall a. a -> Maybe a
Prelude.Just
              (Key
"DeliveryStreamName" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
Data..= Text
deliveryStreamName),
            forall a. a -> Maybe a
Prelude.Just (Key
"Record" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
Data..= Record
record)
          ]
      )

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

instance Data.ToQuery PutRecord where
  toQuery :: PutRecord -> QueryString
toQuery = forall a b. a -> b -> a
Prelude.const forall a. Monoid a => a
Prelude.mempty

-- | /See:/ 'newPutRecordResponse' smart constructor.
data PutRecordResponse = PutRecordResponse'
  { -- | Indicates whether server-side encryption (SSE) was enabled during this
    -- operation.
    PutRecordResponse -> Maybe Bool
encrypted :: Prelude.Maybe Prelude.Bool,
    -- | The response's http status code.
    PutRecordResponse -> Int
httpStatus :: Prelude.Int,
    -- | The ID of the record.
    PutRecordResponse -> Text
recordId :: Prelude.Text
  }
  deriving (PutRecordResponse -> PutRecordResponse -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PutRecordResponse -> PutRecordResponse -> Bool
$c/= :: PutRecordResponse -> PutRecordResponse -> Bool
== :: PutRecordResponse -> PutRecordResponse -> Bool
$c== :: PutRecordResponse -> PutRecordResponse -> Bool
Prelude.Eq, ReadPrec [PutRecordResponse]
ReadPrec PutRecordResponse
Int -> ReadS PutRecordResponse
ReadS [PutRecordResponse]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [PutRecordResponse]
$creadListPrec :: ReadPrec [PutRecordResponse]
readPrec :: ReadPrec PutRecordResponse
$creadPrec :: ReadPrec PutRecordResponse
readList :: ReadS [PutRecordResponse]
$creadList :: ReadS [PutRecordResponse]
readsPrec :: Int -> ReadS PutRecordResponse
$creadsPrec :: Int -> ReadS PutRecordResponse
Prelude.Read, Int -> PutRecordResponse -> ShowS
[PutRecordResponse] -> ShowS
PutRecordResponse -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PutRecordResponse] -> ShowS
$cshowList :: [PutRecordResponse] -> ShowS
show :: PutRecordResponse -> String
$cshow :: PutRecordResponse -> String
showsPrec :: Int -> PutRecordResponse -> ShowS
$cshowsPrec :: Int -> PutRecordResponse -> ShowS
Prelude.Show, forall x. Rep PutRecordResponse x -> PutRecordResponse
forall x. PutRecordResponse -> Rep PutRecordResponse x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep PutRecordResponse x -> PutRecordResponse
$cfrom :: forall x. PutRecordResponse -> Rep PutRecordResponse x
Prelude.Generic)

-- |
-- Create a value of 'PutRecordResponse' 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:
--
-- 'encrypted', 'putRecordResponse_encrypted' - Indicates whether server-side encryption (SSE) was enabled during this
-- operation.
--
-- 'httpStatus', 'putRecordResponse_httpStatus' - The response's http status code.
--
-- 'recordId', 'putRecordResponse_recordId' - The ID of the record.
newPutRecordResponse ::
  -- | 'httpStatus'
  Prelude.Int ->
  -- | 'recordId'
  Prelude.Text ->
  PutRecordResponse
newPutRecordResponse :: Int -> Text -> PutRecordResponse
newPutRecordResponse Int
pHttpStatus_ Text
pRecordId_ =
  PutRecordResponse'
    { $sel:encrypted:PutRecordResponse' :: Maybe Bool
encrypted = forall a. Maybe a
Prelude.Nothing,
      $sel:httpStatus:PutRecordResponse' :: Int
httpStatus = Int
pHttpStatus_,
      $sel:recordId:PutRecordResponse' :: Text
recordId = Text
pRecordId_
    }

-- | Indicates whether server-side encryption (SSE) was enabled during this
-- operation.
putRecordResponse_encrypted :: Lens.Lens' PutRecordResponse (Prelude.Maybe Prelude.Bool)
putRecordResponse_encrypted :: Lens' PutRecordResponse (Maybe Bool)
putRecordResponse_encrypted = forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
Lens.lens (\PutRecordResponse' {Maybe Bool
encrypted :: Maybe Bool
$sel:encrypted:PutRecordResponse' :: PutRecordResponse -> Maybe Bool
encrypted} -> Maybe Bool
encrypted) (\s :: PutRecordResponse
s@PutRecordResponse' {} Maybe Bool
a -> PutRecordResponse
s {$sel:encrypted:PutRecordResponse' :: Maybe Bool
encrypted = Maybe Bool
a} :: PutRecordResponse)

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

-- | The ID of the record.
putRecordResponse_recordId :: Lens.Lens' PutRecordResponse Prelude.Text
putRecordResponse_recordId :: Lens' PutRecordResponse Text
putRecordResponse_recordId = forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
Lens.lens (\PutRecordResponse' {Text
recordId :: Text
$sel:recordId:PutRecordResponse' :: PutRecordResponse -> Text
recordId} -> Text
recordId) (\s :: PutRecordResponse
s@PutRecordResponse' {} Text
a -> PutRecordResponse
s {$sel:recordId:PutRecordResponse' :: Text
recordId = Text
a} :: PutRecordResponse)

instance Prelude.NFData PutRecordResponse where
  rnf :: PutRecordResponse -> ()
rnf PutRecordResponse' {Int
Maybe Bool
Text
recordId :: Text
httpStatus :: Int
encrypted :: Maybe Bool
$sel:recordId:PutRecordResponse' :: PutRecordResponse -> Text
$sel:httpStatus:PutRecordResponse' :: PutRecordResponse -> Int
$sel:encrypted:PutRecordResponse' :: PutRecordResponse -> Maybe Bool
..} =
    forall a. NFData a => a -> ()
Prelude.rnf Maybe Bool
encrypted
      seq :: forall a b. a -> b -> b
`Prelude.seq` forall a. NFData a => a -> ()
Prelude.rnf Int
httpStatus
      seq :: forall a b. a -> b -> b
`Prelude.seq` forall a. NFData a => a -> ()
Prelude.rnf Text
recordId