Skip to content

Commit

Permalink
Merge remote-tracking branch 'springwolf/master' into feat/generic-bi…
Browse files Browse the repository at this point in the history
…ndings

# Conflicts:
#	README.md
  • Loading branch information
timonback committed Oct 13, 2023
2 parents 1a82646 + 359599f commit cb45598
Show file tree
Hide file tree
Showing 41 changed files with 1,257 additions and 7 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/springwolf-plugins.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:

strategy:
matrix:
plugin: [ "amqp", "cloud-stream", "kafka", "sqs" ]
plugin: [ "amqp", "cloud-stream", "kafka", "sns", "sqs" ]

env:
plugin: springwolf-plugins/springwolf-${{ matrix.plugin }}-plugin
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ The documentation and quickstart is available on [springwolf.dev](https://www.sp
### Why You Should Use It

Springwolf exploits the fact that you already fully described your consumer endpoint (with listener annotations, such as
`@KafkaListner`, `@RabbitListener`, `@SqsListener`, etc.) and generates the documentation based on this information.
`@KafkaListener`, `@RabbitListener`, `@SqsListener`, etc.) and generates the documentation based on this information.

#### Share API Schema Definition

Expand All @@ -57,6 +57,7 @@ More details in the documentation.
|-------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [Core](https://github.com/springwolf/springwolf-core/tree/master/springwolf-core) | | ![Maven Central](https://img.shields.io/maven-central/v/io.github.springwolf/springwolf-core?color=green&label=springwolf-core&style=plastic) | ![Sonatype Nexus (Snapshots)](https://img.shields.io/nexus/s/io.github.springwolf/springwolf-core?label=springwolf-core&server=https%3A%2F%2Fs01.oss.sonatype.org&style=plastic) |
| [AMQP](https://github.com/springwolf/springwolf-core/tree/master/springwolf-plugins/springwolf-amqp-plugin) | [AMQP Example](https://github.com/springwolf/springwolf-core/tree/master/springwolf-examples/springwolf-amqp-example) | ![Maven Central](https://img.shields.io/maven-central/v/io.github.springwolf/springwolf-amqp?color=green&label=springwolf-amqp&style=plastic) | ![Sonatype Nexus (Snapshots)](https://img.shields.io/nexus/s/io.github.springwolf/springwolf-amqp?label=springwolf-amqp&server=https%3A%2F%2Fs01.oss.sonatype.org&style=plastic) |
| [AWS SNS](https://github.com/springwolf/springwolf-core/tree/master/springwolf-plugins/springwolf-sns-plugin) | [AWS SNS Example](https://github.com/springwolf/springwolf-core/tree/master/springwolf-examples/springwolf-sns-example) | ![Maven Central](https://img.shields.io/maven-central/v/io.github.springwolf/springwolf-sns?color=green&label=springwolf-sqs&style=plastic) | ![Sonatype Nexus (Snapshots)](https://img.shields.io/nexus/s/io.github.springwolf/springwolf-sns?label=springwolf-sns&server=https%3A%2F%2Fs01.oss.sonatype.org&style=plastic) |
| [AWS SQS](https://github.com/springwolf/springwolf-core/tree/master/springwolf-plugins/springwolf-sqs-plugin) | [AWS SQS Example](https://github.com/springwolf/springwolf-core/tree/master/springwolf-examples/springwolf-sqs-example) | ![Maven Central](https://img.shields.io/maven-central/v/io.github.springwolf/springwolf-sqs?color=green&label=springwolf-sqs&style=plastic) | ![Sonatype Nexus (Snapshots)](https://img.shields.io/nexus/s/io.github.springwolf/springwolf-sqs?label=springwolf-sqs&server=https%3A%2F%2Fs01.oss.sonatype.org&style=plastic) |
| [Cloud Stream](https://github.com/springwolf/springwolf-core/tree/master/springwolf-plugins/springwolf-cloud-stream-plugin) | [Cloud Stream Example](https://github.com/springwolf/springwolf-core/tree/master/springwolf-examples/springwolf-cloud-stream-example) | ![Maven Central](https://img.shields.io/maven-central/v/io.github.springwolf/springwolf-cloud-stream?color=green&label=springwolf-cloud-stream&style=plastic) | ![Sonatype Nexus (Snapshots)](https://img.shields.io/nexus/s/io.github.springwolf/springwolf-cloud-stream?label=springwolf-cloud-stream&server=https%3A%2F%2Fs01.oss.sonatype.org&style=plastic) |
| [Kafka](https://github.com/springwolf/springwolf-core/tree/master/springwolf-plugins/springwolf-kafka-plugin) | [Kafka Example](https://github.com/springwolf/springwolf-core/tree/master/springwolf-examples/springwolf-kafka-example) | ![Maven Central](https://img.shields.io/maven-central/v/io.github.springwolf/springwolf-kafka?color=green&label=springwolf-kafka&style=plastic) | ![Sonatype Nexus (Snapshots)](https://img.shields.io/nexus/s/io.github.springwolf/springwolf-kafka?label=springwolf-kafka&server=https%3A%2F%2Fs01.oss.sonatype.org&style=plastic) |
Expand Down
3 changes: 2 additions & 1 deletion RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ The following list describe the steps necessary to release a new version.
1. AMQP: https://amqp.demo.springwolf.dev/
2. CloudStream https://cloud-stream.demo.springwolf.dev/
3. Kafka: https://kafka.demo.springwolf.dev/
4. SQS: https://sqs.demo.springwolf.dev/
4. SNS: https://sns.demo.springwolf.dev/
5. SQS: https://sqs.demo.springwolf.dev/
3. Remove the `-SNAPHSOT` postfix in `.env`, create a new branch `release/0.X.X` (version number), commit & push
4. Run GitHub `Publish releases` pipeline from the newly created release branch
5. Release version in nexus
Expand Down
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ allprojects {
project.name == 'springwolf-amqp' ||
project.name == 'springwolf-cloud-stream' ||
project.name == 'springwolf-kafka' ||
project.name == 'springwolf-sns' ||
project.name == 'springwolf-sqs' ||
project.name == 'springwolf-ui' ||
project.name == 'springwolf-common-model-converters' ||
Expand Down
3 changes: 3 additions & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ include(
'springwolf-plugins:springwolf-amqp-plugin',
'springwolf-plugins:springwolf-cloud-stream-plugin',
'springwolf-plugins:springwolf-kafka-plugin',
'springwolf-plugins:springwolf-sns-plugin',
'springwolf-plugins:springwolf-sqs-plugin',
'springwolf-examples:springwolf-amqp-example',
'springwolf-examples:springwolf-cloud-stream-example',
'springwolf-examples:springwolf-kafka-example',
'springwolf-examples:springwolf-sns-example',
'springwolf-examples:springwolf-sqs-example',
'springwolf-ui',
'springwolf-add-ons:springwolf-common-model-converters',
Expand All @@ -18,5 +20,6 @@ include(
project(':springwolf-plugins:springwolf-amqp-plugin').name = 'springwolf-amqp'
project(':springwolf-plugins:springwolf-cloud-stream-plugin').name = 'springwolf-cloud-stream'
project(':springwolf-plugins:springwolf-kafka-plugin').name = 'springwolf-kafka'
project(':springwolf-plugins:springwolf-sns-plugin').name = 'springwolf-sns'
project(':springwolf-plugins:springwolf-sqs-plugin').name = 'springwolf-sqs'

2 changes: 1 addition & 1 deletion springwolf-examples/springwolf-amqp-example/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ plugins {
id 'io.spring.dependency-management'
id 'ca.cutterslade.analyze'

id 'com.bmuschko.docker-spring-boot-application' version '9.3.4'
id 'com.bmuschko.docker-spring-boot-application'
}

dependencies {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {
id 'org.springframework.boot'
id 'io.spring.dependency-management'
id 'ca.cutterslade.analyze'
id 'com.bmuschko.docker-spring-boot-application' version '9.3.4'
id 'com.bmuschko.docker-spring-boot-application'
}

ext {
Expand Down
2 changes: 1 addition & 1 deletion springwolf-examples/springwolf-kafka-example/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ plugins {
id 'io.spring.dependency-management'
id 'ca.cutterslade.analyze'

id 'com.bmuschko.docker-spring-boot-application' version '9.3.4'
id 'com.bmuschko.docker-spring-boot-application'
id 'org.springdoc.openapi-gradle-plugin' version '1.7.0'
}

Expand Down
1 change: 1 addition & 0 deletions springwolf-examples/springwolf-sns-example/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SPRINGWOLF_VERSION=0.16.0-SNAPSHOT
6 changes: 6 additions & 0 deletions springwolf-examples/springwolf-sns-example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
## Usage

### Run with docker compose (recommended)
1. Copy the `docker-compose.yml` file to your machine.
2. Run `$ docker-compose up`.
3. Visit `localhost:8080/springwolf/asyncapi-ui.html` or try the API: `$ curl localhost:8080/springwolf/docs`.
76 changes: 76 additions & 0 deletions springwolf-examples/springwolf-sns-example/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
plugins {
id 'java'

id 'org.springframework.boot'
id 'io.spring.dependency-management'
id 'ca.cutterslade.analyze'

id 'com.bmuschko.docker-spring-boot-application'
}

dependencyManagement {
imports {
mavenBom "io.awspring.cloud:spring-cloud-aws-dependencies:3.0.2"
}
}

dependencies {
implementation project(":springwolf-core")
implementation project(":springwolf-plugins:springwolf-sns")

annotationProcessor project(":springwolf-plugins:springwolf-sns")
runtimeOnly project(":springwolf-ui")

runtimeOnly "org.springframework.boot:spring-boot-starter-web"

implementation "org.slf4j:slf4j-api:${slf4jApiVersion}"
implementation "io.swagger.core.v3:swagger-annotations:${swaggerVersion}"

implementation 'io.awspring.cloud:spring-cloud-aws-sns'
implementation 'io.awspring.cloud:spring-cloud-aws-starter-sns'
permitUnusedDeclared 'io.awspring.cloud:spring-cloud-aws-starter-sns'
implementation "org.springframework.boot:spring-boot-autoconfigure"
implementation "org.springframework.boot:spring-boot"
implementation "org.springframework:spring-context"
implementation "org.springframework:spring-messaging"

testRuntimeOnly "org.junit.jupiter:junit-jupiter:${junitJupiterVersion}"

testImplementation "com.vaadin.external.google:android-json:${androidJsonVersion}"

testImplementation "org.junit.jupiter:junit-jupiter-api:${junitJupiterVersion}"

testImplementation "org.springframework.boot:spring-boot-test"
testImplementation "org.springframework:spring-beans"
testImplementation "org.springframework:spring-web"
testImplementation "org.springframework:spring-test"

testImplementation "org.testcontainers:testcontainers:${testcontainersVersion}"
testImplementation "org.testcontainers:junit-jupiter:${testcontainersVersion}"
testImplementation "org.testcontainers:localstack:${testcontainersVersion}"
}

docker {
springBootApplication {
maintainer = '[email protected]'
baseImage = 'eclipse-temurin:17-jre-focal'
ports = [8080]
images = ["stavshamir/springwolf-sns-example:${project.version}"]
}

registryCredentials {
username = project.findProperty('DOCKERHUB_USERNAME') ?: ''
password = project.findProperty('DOCKERHUB_TOKEN') ?: ''
}
}

test {
dependsOn dockerBuildImage
dependsOn spotlessApply // Automatically fix code formatting if possible

useJUnitPlatform()

testLogging {
exceptionFormat = 'full'
}
}
36 changes: 36 additions & 0 deletions springwolf-examples/springwolf-sns-example/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
version: '3'
services:
app:
image: stavshamir/springwolf-sns-example:${SPRINGWOLF_VERSION}
links:
- localstack
environment:
- SPRING_CLOUD_AWS_ENDPOINT=http://localstack:4566
ports:
- "8080:8080"
depends_on:
- localstack

localstack:
image: localstack/localstack:2.2.0
environment:
- DEBUG=${DEBUG-}
- AWS_REGION=eu-central-1
- SERVICES=sqs,sns
ports:
- "4566:4566" # LocalStack Gateway
# - "4510-4559:4510-4559" # external services port range
volumes:
- "${TMPDIR:-/tmp/localstack}:/tmp/localstack"
- "/var/run/docker.sock:/var/run/docker.sock"
localstack_setup:
image: localstack/localstack:2.2.0
links:
- localstack
depends_on:
- localstack
restart: "no"
entrypoint: [ "bash", "-c", "
awslocal --endpoint-url=http://localstack:4566 sns create-topic --name another-topic --region eu-central-1;
awslocal --endpoint-url=http://localstack:4566 sns create-topic --name example-topic --region eu-central-1;
" ]
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-License-Identifier: Apache-2.0
package io.github.stavshamir.springwolf.example.sns;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringwolfSnsExampleApplication {

public static void main(String[] args) {
SpringApplication.run(SpringwolfSnsExampleApplication.class, args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// SPDX-License-Identifier: Apache-2.0
package io.github.stavshamir.springwolf.example.sns.consumers;

import io.github.stavshamir.springwolf.asyncapi.scanners.channels.operationdata.annotation.AsyncListener;
import io.github.stavshamir.springwolf.asyncapi.scanners.channels.operationdata.annotation.AsyncOperation;
import io.github.stavshamir.springwolf.asyncapi.scanners.channels.operationdata.annotation.SnsAsyncOperationBinding;
import io.github.stavshamir.springwolf.example.sns.dtos.AnotherPayloadDto;
import io.github.stavshamir.springwolf.example.sns.dtos.ExamplePayloadDto;
import io.github.stavshamir.springwolf.example.sns.producers.AnotherProducer;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
@Slf4j
public class ExampleConsumer {
private final AnotherProducer anotherProducer;

@AsyncListener(operation = @AsyncOperation(channelName = "example-topic"))
@SnsAsyncOperationBinding
public void receiveExamplePayload(ExamplePayloadDto payload) {
log.info("Received new message in example-topic: {}", payload.toString());

AnotherPayloadDto example = new AnotherPayloadDto();
example.setExample(payload);
example.setFoo("foo");

anotherProducer.sendMessage(example);
}

@AsyncListener(operation = @AsyncOperation(channelName = "another-topic"))
@SnsAsyncOperationBinding
public void receiveAnotherPayload(AnotherPayloadDto payload) {
log.info("Received new message in another-topic: {}", payload.toString());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// SPDX-License-Identifier: Apache-2.0
package io.github.stavshamir.springwolf.example.sns.dtos;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.NOT_REQUIRED;
import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;

@Schema(description = "Another payload model")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class AnotherPayloadDto {

@Schema(description = "Foo field", example = "bar", requiredMode = NOT_REQUIRED)
private String foo;

@Schema(description = "Example field", requiredMode = REQUIRED)
private ExamplePayloadDto example;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// SPDX-License-Identifier: Apache-2.0
package io.github.stavshamir.springwolf.example.sns.dtos;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;

@Schema(description = "Example payload model")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ExamplePayloadDto {
@Schema(description = "Some string field", example = "some string value", requiredMode = REQUIRED)
private String someString;

@Schema(description = "Some long field", example = "5")
private long someLong;

@Schema(description = "Some enum field", example = "FOO2", requiredMode = REQUIRED)
private ExampleEnum someEnum;

public enum ExampleEnum {
FOO1,
FOO2,
FOO3
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-License-Identifier: Apache-2.0
package io.github.stavshamir.springwolf.example.sns.producers;

import io.awspring.cloud.sns.core.SnsTemplate;
import io.github.stavshamir.springwolf.asyncapi.scanners.channels.operationdata.annotation.AsyncOperation;
import io.github.stavshamir.springwolf.asyncapi.scanners.channels.operationdata.annotation.AsyncPublisher;
import io.github.stavshamir.springwolf.asyncapi.scanners.channels.operationdata.annotation.SnsAsyncOperationBinding;
import io.github.stavshamir.springwolf.example.sns.dtos.AnotherPayloadDto;
import lombok.RequiredArgsConstructor;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class AnotherProducer {
private final SnsTemplate template;

public static final String TOPIC = "another-topic";

@AsyncPublisher(
operation =
@AsyncOperation(
channelName = TOPIC,
description = "Custom, optional description defined in the AsyncPublisher annotation"))
@SnsAsyncOperationBinding
public void sendMessage(AnotherPayloadDto msg) {
template.send(TOPIC, MessageBuilder.withPayload(msg).build());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#########
# Spring configuration
spring.application.name=Springwolf example project - SNS


#########
# Spring AWS configuration
spring.cloud.aws.endpoint=http://localhost:4566
spring.cloud.aws.region.static=eu-central-1
spring.cloud.aws.stack.auto=false
spring.cloud.aws.stack.enabled=false
spring.cloud.aws.credentials.secretKey=ABC
spring.cloud.aws.credentials.accessKey=XYZ


#########
# Springwolf configuration
springwolf.enabled=true
springwolf.docket.base-package=io.github.stavshamir.springwolf.example.sns
springwolf.docket.info.title=${spring.application.name}
springwolf.docket.info.version=1.0.0
springwolf.docket.info.description=Springwolf example project to demonstrate springwolfs abilities
springwolf.docket.info.terms-of-service=http://asyncapi.org/terms
springwolf.docket.info.contact.name=springwolf
springwolf.docket.info.contact.email=[email protected]
springwolf.docket.info.contact.url=https://github.com/springwolf/springwolf-core
springwolf.docket.info.license.name=Apache License 2.0
springwolf.docket.servers.sns.protocol=sns
springwolf.docket.servers.sns.url=http://localhost:4566

springwolf.plugin.sns.publishing.enabled=true


# For debugging purposes
logging.level.io.github.stavshamir.springwolf=DEBUG
Loading

0 comments on commit cb45598

Please sign in to comment.