Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
da4652f
ci: speed up tests by only running sqs tests
wochinge Aug 9, 2023
cd20a13
chore: prepare split in sqs and sns
wochinge Aug 9, 2023
2b7ef02
chore: wrap up split for foundation
wochinge Aug 9, 2023
6941cd0
refactor: separate config
wochinge Aug 9, 2023
0ac39cb
refactor: implement separate publisher
wochinge Aug 9, 2023
f9e7148
refactor: drop no longer needed message builder
wochinge Aug 9, 2023
891e119
refactor: extract error type
wochinge Aug 10, 2023
8311045
style: name variable correctly
wochinge Aug 10, 2023
8c4addd
feat: add sns 🎉
wochinge Aug 10, 2023
5b42a29
refactor: abstract retry logic
wochinge Aug 10, 2023
b8bdc9c
chore: remove sqs from shared modules
wochinge Aug 10, 2023
829db54
chore: cleanup
wochinge Aug 10, 2023
36b0a59
chore: drop temporary changes
wochinge Aug 10, 2023
e76af5f
chore: update mod to include sns module
wochinge Aug 10, 2023
6be88d4
refactor: move healthcheck out of config into separate function
wochinge Aug 11, 2023
07e1938
refactor: simplify request builder setup
wochinge Aug 11, 2023
14c2b67
refactor: message id
ArzelaAscoIi Aug 14, 2023
0ed0b62
nit: make functions just visibile in sub module
ArzelaAscoIi Aug 15, 2023
33c7c6f
fix: add pub(super)
ArzelaAscoIi Aug 15, 2023
d3b5a6a
fix: sub methods attributes pub(super)
ArzelaAscoIi Aug 15, 2023
89c00c3
Update Cargo.toml
ArzelaAscoIi Aug 16, 2023
4a641a3
Update src/sinks/aws_s_s/mod.rs
ArzelaAscoIi Aug 16, 2023
129313c
Update src/sinks/aws_s_s/retry.rs
ArzelaAscoIi Aug 16, 2023
efdf844
Update src/sinks/mod.rs
ArzelaAscoIi Aug 16, 2023
e7fe94c
Update src/sinks/aws_s_s/sns/config.rs
ArzelaAscoIi Aug 16, 2023
a7c7cf7
chore: first bunch of comments
ArzelaAscoIi Aug 16, 2023
8f3be55
Merge branch 'feat/sns' of github.com:wochinge/vector into feat/sns
ArzelaAscoIi Aug 16, 2023
69890db
chore: second bunch of comments
ArzelaAscoIi Aug 16, 2023
6a51b9e
chore: enable all integration tests
ArzelaAscoIi Aug 17, 2023
345d147
fix: move test
ArzelaAscoIi Aug 17, 2023
5308c0e
fix: dead_code warning
ArzelaAscoIi Aug 17, 2023
4df0786
fix: dead code warning
ArzelaAscoIi Aug 17, 2023
a2223eb
docs: autogenerated aws_sns docs
ArzelaAscoIi Aug 17, 2023
8dbb7be
fix: move region serde to downstream impl
ArzelaAscoIi Aug 17, 2023
185fe20
update licenses
neuronull Aug 17, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -771,13 +771,13 @@ amqp-integration-tests = ["sources-amqp", "sinks-amqp"]
appsignal-integration-tests = ["sinks-appsignal"]

aws-integration-tests = [
"aws-cloudwatch-logs-integration-tests",
"aws-cloudwatch-metrics-integration-tests",
"aws-ec2-metadata-integration-tests",
"aws-ecs-metrics-integration-tests",
"aws-kinesis-firehose-integration-tests",
"aws-kinesis-streams-integration-tests",
"aws-s3-integration-tests",
# "aws-cloudwatch-logs-integration-tests",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll revert these later - this is just to speed up testing

# "aws-cloudwatch-metrics-integration-tests",
# "aws-ec2-metadata-integration-tests",
# "aws-ecs-metrics-integration-tests",
# "aws-kinesis-firehose-integration-tests",
# "aws-kinesis-streams-integration-tests",
# "aws-s3-integration-tests",
Comment thread
neuronull marked this conversation as resolved.
Outdated
"aws-sqs-integration-tests",
]

Expand All @@ -792,7 +792,7 @@ aws-ecs-metrics-integration-tests = ["sources-aws_ecs_metrics"]
aws-kinesis-firehose-integration-tests = ["sinks-aws_kinesis_firehose", "dep:aws-sdk-elasticsearch", "sinks-elasticsearch"]
aws-kinesis-streams-integration-tests = ["sinks-aws_kinesis_streams"]
aws-s3-integration-tests = ["sinks-aws_s3", "sources-aws_s3"]
aws-sqs-integration-tests = ["sinks-aws_sqs", "sources-aws_sqs"]
aws-sqs-integration-tests = ["sinks-aws_sqs"] #, "sources-aws_sqs"]
Comment thread
ArzelaAscoIi marked this conversation as resolved.
Outdated
axiom-integration-tests = ["sinks-axiom"]
azure-blob-integration-tests = ["sinks-azure_blob"]
chronicle-integration-tests = ["sinks-gcp"]
Expand Down
11 changes: 11 additions & 0 deletions src/sinks/aws_s_s/client.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use super::{request_builder::SendMessageEntry, service::SendMessageResponse};
use aws_sdk_sqs::{error::SendMessageError, types::SdkError};

#[async_trait::async_trait]
pub trait Client {
async fn send_message(
&self,
entry: SendMessageEntry,
byte_size: usize,
) -> Result<SendMessageResponse, SdkError<SendMessageError>>;
}
92 changes: 12 additions & 80 deletions src/sinks/aws_sqs/config.rs → src/sinks/aws_s_s/config.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
use std::convert::TryFrom;

use aws_sdk_sqs::Client as SqsClient;
use futures::FutureExt;
use serde::{Deserialize, Serialize};
use snafu::{ResultExt, Snafu};

use vector_config::configurable_component;

use crate::{
aws::{create_client, AwsAuthentication, RegionOrEndpoint},
aws::{AwsAuthentication, RegionOrEndpoint},
codecs::EncodingConfig,
common::sqs::SqsClientBuilder,
config::{
AcknowledgementsConfig, DataType, GenerateConfig, Input, ProxyConfig, SinkConfig,
SinkContext,
},
config::AcknowledgementsConfig,
sinks::util::TowerRequestConfig,
template::{Template, TemplateParseError},
tls::TlsConfig,
Expand All @@ -32,20 +27,10 @@ pub(super) enum BuildError {
}

/// Configuration for the `aws_sqs` sink.
Comment thread
neuronull marked this conversation as resolved.
Outdated
#[configurable_component(sink(
"aws_sqs",
"Publish observability events to AWS Simple Queue Service topics."
))]
#[configurable_component]
#[derive(Clone, Debug)]
#[serde(deny_unknown_fields)]
pub struct SqsSinkConfig {
/// The URL of the Amazon SQS queue to which messages are sent.
#[configurable(validation(format = "uri"))]
#[configurable(metadata(
docs::examples = "https://sqs.us-east-2.amazonaws.com/123456789012/MyQueue"
))]
pub queue_url: String,

pub struct BaseSSSinkConfig {
#[serde(flatten)]
pub region: RegionOrEndpoint,

Expand Down Expand Up @@ -102,68 +87,14 @@ pub enum Encoding {
Json,
}

impl GenerateConfig for SqsSinkConfig {
fn generate_config() -> toml::Value {
toml::from_str(
r#"queue_url = "https://sqs.us-east-2.amazonaws.com/123456789012/MyQueue"
region = "us-east-2"
encoding.codec = "json""#,
)
.unwrap()
}
}

#[async_trait::async_trait]
#[typetag::serde(name = "aws_sqs")]
impl SinkConfig for SqsSinkConfig {
async fn build(
&self,
cx: SinkContext,
) -> crate::Result<(crate::sinks::VectorSink, crate::sinks::Healthcheck)> {
let client = self.create_client(&cx.proxy).await?;
let healthcheck = self.clone().healthcheck(client.clone()).boxed();
let sink = super::sink::SqsSink::new(self.clone(), client)?;
Ok((
crate::sinks::VectorSink::from_event_streamsink(sink),
healthcheck,
))
}

fn input(&self) -> Input {
Input::new(self.encoding.config().input_type() & DataType::Log)
}

fn acknowledgements(&self) -> &AcknowledgementsConfig {
&self.acknowledgements
}
#[derive(Clone, Debug)]
pub struct ConfigWithIds {
Comment thread
neuronull marked this conversation as resolved.
Outdated
pub base_config: BaseSSSinkConfig,
pub fifo: bool,
}

impl SqsSinkConfig {
pub async fn healthcheck(self, client: SqsClient) -> crate::Result<()> {
client
.get_queue_attributes()
.queue_url(self.queue_url.clone())
.send()
.await
.map(|_| ())
.map_err(Into::into)
}

pub async fn create_client(&self, proxy: &ProxyConfig) -> crate::Result<SqsClient> {
create_client::<SqsClientBuilder>(
&self.auth,
self.region.region(),
self.region.endpoint(),
proxy,
&self.tls,
true,
)
.await
}

impl ConfigWithIds {
pub fn message_group_id(&self) -> crate::Result<Option<Template>> {
let fifo = self.queue_url.ends_with(".fifo");
match (self.message_group_id.as_ref(), fifo) {
match (self.base_config.message_group_id.as_ref(), self.fifo) {
(Some(value), true) => Ok(Some(
Template::try_from(value.clone()).context(TopicTemplateSnafu)?,
)),
Expand All @@ -175,6 +106,7 @@ impl SqsSinkConfig {

pub fn message_deduplication_id(&self) -> crate::Result<Option<Template>> {
Ok(self
.base_config
.message_deduplication_id
.clone()
.map(Template::try_from)
Expand Down
12 changes: 12 additions & 0 deletions src/sinks/aws_s_s/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
pub mod config;
Comment thread
neuronull marked this conversation as resolved.
Outdated
mod request_builder;
mod retry;
mod service;
mod sink;

pub use self::config::BaseSSSinkConfig;

#[cfg(feature = "sinks-aws_sqs")]
pub mod sqs;

mod client;
Comment thread
neuronull marked this conversation as resolved.
Outdated
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use bytes::Bytes;
use vector_common::request_metadata::{MetaDescriptive, RequestMetadata};
use vector_core::ByteSizeOf;

use super::config::SqsSinkConfig;
use crate::sinks::aws_s_s::config::ConfigWithIds;
use crate::{
codecs::{Encoder, Transformer},
event::{Event, EventFinalizers, Finalizable},
Expand All @@ -26,20 +26,18 @@ pub(crate) struct SqsRequestBuilder {
encoder: (Transformer, Encoder<()>),
message_group_id: Option<Template>,
message_deduplication_id: Option<Template>,
queue_url: String,
}

impl SqsRequestBuilder {
pub fn new(config: SqsSinkConfig) -> crate::Result<Self> {
let transformer = config.encoding.transformer();
let serializer = config.encoding.build()?;
pub fn new(config: ConfigWithIds) -> crate::Result<Self> {
let transformer = config.base_config.encoding.transformer();
let serializer = config.base_config.encoding.build()?;
let encoder = Encoder::<()>::new(serializer);

Ok(Self {
encoder: (transformer, encoder),
message_group_id: config.message_group_id()?,
message_deduplication_id: config.message_deduplication_id()?,
queue_url: config.queue_url,
})
}
}
Expand Down Expand Up @@ -116,20 +114,18 @@ impl RequestBuilder<Event> for SqsRequestBuilder {
message_body,
message_group_id: sqs_metadata.message_group_id,
message_deduplication_id: sqs_metadata.message_deduplication_id,
queue_url: self.queue_url.clone(),
finalizers: sqs_metadata.finalizers,
metadata,
}
}
}

#[derive(Debug, Clone)]
pub(crate) struct SendMessageEntry {
pub struct SendMessageEntry {
pub message_body: String,
pub message_group_id: Option<String>,
pub message_deduplication_id: Option<String>,
pub queue_url: String,
finalizers: EventFinalizers,
pub finalizers: EventFinalizers,
pub metadata: RequestMetadata,
}

Expand Down
File renamed without changes.
67 changes: 67 additions & 0 deletions src/sinks/aws_s_s/service.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
use std::task::{Context, Poll};

use aws_sdk_sqs::{error::SendMessageError, types::SdkError};
use futures::future::BoxFuture;
use tower::Service;
use vector_common::request_metadata::GroupedCountByteSize;
use vector_core::{event::EventStatus, stream::DriverResponse, ByteSizeOf};

use super::{client::Client, request_builder::SendMessageEntry};

#[derive(Clone)]
pub(crate) struct SqsService<C>
Comment thread
wochinge marked this conversation as resolved.
Outdated
where
C: Client + Clone + Send + Sync + 'static,
{
client: C,
}

impl<C> SqsService<C>
where
C: Client + Clone + Send + Sync + 'static,
{
pub const fn new(client: C) -> Self {
Self { client }
}
}

impl<C> Service<SendMessageEntry> for SqsService<C>
where
C: Client + Clone + Send + Sync + 'static,
{
type Response = SendMessageResponse;
type Error = SdkError<SendMessageError>;
type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>;

// Emission of an internal event in case of errors is handled upstream by the caller.
fn poll_ready(&mut self, _cx: &mut Context) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}

// Emission of internal events for errors and dropped events is handled upstream by the caller.
fn call(&mut self, entry: SendMessageEntry) -> Self::Future {
let byte_size = entry.size_of();
let client = self.client.clone();

Box::pin(async move { client.send_message(entry, byte_size).await })
}
}

pub struct SendMessageResponse {
pub(crate) byte_size: usize,
pub(crate) json_byte_size: GroupedCountByteSize,
}

impl DriverResponse for SendMessageResponse {
fn event_status(&self) -> EventStatus {
EventStatus::Delivered
}

fn events_sent(&self) -> &GroupedCountByteSize {
&self.json_byte_size
}

fn bytes_sent(&self) -> Option<usize> {
Some(self.byte_size)
}
}
27 changes: 18 additions & 9 deletions src/sinks/aws_sqs/sink.rs → src/sinks/aws_s_s/sink.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use std::num::NonZeroUsize;

use aws_sdk_sqs::Client as SqsClient;
use futures::stream::BoxStream;
use futures_util::StreamExt;
use vector_core::sink::StreamSink;

use super::{config::SqsSinkConfig, request_builder::SqsRequestBuilder, service::SqsService};
use super::{client::Client, request_builder::SqsRequestBuilder, service::SqsService};
use crate::internal_events::SinkRequestBuildError;
use crate::sinks::aws_s_s::config::ConfigWithIds;
use crate::{
event::Event,
sinks::util::{
Expand All @@ -24,18 +24,24 @@ impl SinkBatchSettings for SqsSinkDefaultBatchSettings {
}

#[derive(Clone)]
pub(crate) struct SqsSink {
pub struct SqsSink<C>
where
C: Client + Clone + Send + Sync + 'static,
{
request_builder: SqsRequestBuilder,
service: SqsService,
service: SqsService<C>,
request: TowerRequestConfig,
}

impl SqsSink {
pub fn new(config: SqsSinkConfig, client: SqsClient) -> crate::Result<Self> {
let request = config.request;
impl<C> SqsSink<C>
where
C: Client + Clone + Send + Sync + 'static,
{
pub fn new(config: ConfigWithIds, publisher: C) -> crate::Result<Self> {
let request = config.base_config.request;
Ok(SqsSink {
request_builder: SqsRequestBuilder::new(config)?,
service: SqsService::new(client),
service: SqsService::new(publisher),
request,
})
}
Expand Down Expand Up @@ -64,7 +70,10 @@ impl SqsSink {
}

#[async_trait::async_trait]
impl StreamSink<Event> for SqsSink {
impl<C> StreamSink<Event> for SqsSink<C>
where
C: Client + Clone + Send + Sync + 'static,
{
async fn run(mut self: Box<Self>, input: BoxStream<'_, Event>) -> Result<(), ()> {
self.run_inner(input).await
}
Expand Down
Loading