Skip to content

Commit

Permalink
(feat) add Localstack SNS (#639)
Browse files Browse the repository at this point in the history
* (feat) add Localstack SNS

* fix (simplify) test

* specify build enabled after 2.6.0
  • Loading branch information
lucjross-favor authored Jun 19, 2024
1 parent 5b5d13b commit 504224f
Show file tree
Hide file tree
Showing 10 changed files with 161 additions and 1 deletion.
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,11 @@ spock = { module = "org.spockframework:spock-core", version.ref = "spock" }
amazon-awssdk-v1-dynamodb = { module = "com.amazonaws:aws-java-sdk-dynamodb", version.ref = "amazon-awssdk-v1" }
amazon-awssdk-v1-s3 = { module = "com.amazonaws:aws-java-sdk-s3", version.ref = "amazon-awssdk-v1" }
amazon-awssdk-v1-sqs = { module = "com.amazonaws:aws-java-sdk-sqs", version.ref = "amazon-awssdk-v1" }
amazon-awssdk-v1-sns = { module = "com.amazonaws:aws-java-sdk-sns", version.ref = "amazon-awssdk-v1" }
amazon-awssdk-v2-dynamodb = { module = "software.amazon.awssdk:dynamodb", version.ref = "amazon-awssdk-v2" }
amazon-awssdk-v2-s3 = { module = "software.amazon.awssdk:s3", version.ref = "amazon-awssdk-v2" }
amazon-awssdk-v2-sqs = { module = "software.amazon.awssdk:sqs", version.ref = "amazon-awssdk-v2" }
amazon-awssdk-v2-sns = { module = "software.amazon.awssdk:sns", version.ref = "amazon-awssdk-v2" }

jansi = { module = "org.fusesource.jansi:jansi", version.ref = "jansi" }
#
Expand Down
3 changes: 2 additions & 1 deletion settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ def localstackModules = [
'core',
's3',
'dynamodb',
'sqs'
'sqs',
'sns'
]

include 'test-resources-bom'
Expand Down
1 change: 1 addition & 0 deletions src/main/docs/guide/modules-localstack.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ The following services are supported:
- S3, by providing the `aws.services.s3.endpoint-override` property
- DynamoDB, by providing the `aws.services.dynamodb.endpoint-override` property
- SQS, by providing the `aws.services.sqs.endpoint-override` property
- SNS, by providing the `aws.services.sns.endpoint-override` property
In addition, the following properties will be resolved by test resources:

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
plugins {
id 'io.micronaut.build.internal.localstack-module'
}

micronautBuild {
binaryCompatibility {
enabledAfter '2.6.0'
}
}

description = """
Provides support for Localstack SNS.
"""

dependencies {
implementation(project(":micronaut-test-resources-localstack-core"))
runtimeOnly(libs.amazon.awssdk.v1.sns) {
because "Localstack requires the AWS SDK in version 1 at runtime"
}
testImplementation(testFixtures(project(":micronaut-test-resources-localstack-core")))
testImplementation(libs.amazon.awssdk.v2.sns)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright 2017-2024 original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.micronaut.testresources.localstack.sns;

import io.micronaut.testresources.localstack.LocalStackService;
import org.testcontainers.containers.localstack.LocalStackContainer;

import java.util.Collections;
import java.util.List;
import java.util.Optional;

/**
* Adds support for Localstack SNS.
*/
public class LocalStackSNSService implements LocalStackService {

private static final String AWS_SNS_ENDPOINT_OVERRIDE = "aws.services.sns.endpoint-override";

@Override
public LocalStackContainer.Service getServiceKind() {
return LocalStackContainer.Service.SNS;
}

@Override
public List<String> getResolvableProperties() {
return Collections.singletonList(AWS_SNS_ENDPOINT_OVERRIDE);
}

@Override
public Optional<String> resolveProperty(String propertyName, LocalStackContainer container) {
if (AWS_SNS_ENDPOINT_OVERRIDE.equals(propertyName)) {
return Optional.of(container.getEndpointOverride(LocalStackContainer.Service.SNS).toString());
}
return Optional.empty();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
io.micronaut.testresources.localstack.sns.LocalStackSNSService
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package io.micronaut.testresources.localstack.sns

import io.micronaut.test.extensions.spock.annotation.MicronautTest
import io.micronaut.testresources.localstack.AbstractLocalStackSpec
import jakarta.inject.Inject
import org.junit.Assert
import software.amazon.awssdk.services.sns.SnsClient
import software.amazon.awssdk.services.sns.model.Topic

@MicronautTest
class LocalStackSNSTest extends AbstractLocalStackSpec {

@Inject
SnsClient client

def "automatically starts a SNS container"() {
when:
client.createTopic {
it.name("test-topic")
}

then:
List<Topic> topics = client.listTopics().topics()
Assert.assertEquals(1, topics.size())
Assert.assertTrue(topics[0].topicArn().endsWith("test-topic"))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package io.micronaut.testresources.localstack.sns

import io.micronaut.context.annotation.Factory
import jakarta.inject.Singleton
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider
import software.amazon.awssdk.regions.Region
import software.amazon.awssdk.services.sns.SnsClient

@Factory
class TestSnsClientFactory {

@Singleton
SnsClient snsClient(TestSnsConfig testSnsConfig) {
return SnsClient.builder()
.endpointOverride(new URI(testSnsConfig.sns.endpointOverride))
.credentialsProvider(
StaticCredentialsProvider.create(
AwsBasicCredentials.create(testSnsConfig.accessKeyId, testSnsConfig.secretKey)
)
)
.region(Region.of(testSnsConfig.region))
.build()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package io.micronaut.testresources.localstack.sns

import io.micronaut.context.annotation.ConfigurationBuilder
import io.micronaut.context.annotation.ConfigurationProperties

@ConfigurationProperties("aws")
class TestSnsConfig {
String accessKeyId
String secretKey
String region

@ConfigurationBuilder(configurationPrefix = "services.sns")
final Sns sns = new Sns()

static class Sns {
String endpointOverride
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<configuration>

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>

<root level="info">
<appender-ref ref="STDOUT" />
</root>
</configuration>

0 comments on commit 504224f

Please sign in to comment.