Skip to content

Commit

Permalink
feat(jms): JMS support (#432)
Browse files Browse the repository at this point in the history
* jms

* docs: add @krzysztofxkwiecien as a contributor

* readme & workflows update

* added jms mock to website

* test(jms): fix docker-compose setup

* test: Add MessageBindingProcessor and OperationBindingProcessor coverage

* test(jms): add controller and binding tests

* chore: prepare jms artifact

---------

Co-authored-by: Timon Back <timonback@users.noreply.github.com>
Co-authored-by: sam0r040 <93372330+sam0r040@users.noreply.github.com>
  • Loading branch information
3 people authored Nov 24, 2023
1 parent 4668e5e commit 491e1aa
Show file tree
Hide file tree
Showing 57 changed files with 2,269 additions and 12 deletions.
9 changes: 9 additions & 0 deletions .all-contributorsrc
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,15 @@
"contributions": [
"code"
]
},
{
"login": "krzysztofxkwiecien",
"name": "Krzysztof Kwiecień",
"avatar_url": "https://avatars.githubusercontent.com/u/37042650?v=4",
"profile": "https://github.com/krzysztofxkwiecien",
"contributions": [
"code"
]
}
],
"contributorsPerLine": 7,
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/springwolf-plugins.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
strategy:
fail-fast: false
matrix:
plugin: [ "amqp", "cloud-stream", "kafka", "sns", "sqs" ]
plugin: [ "amqp", "cloud-stream", "jms", "kafka", "sns", "sqs" ]

env:
plugin: springwolf-plugins/springwolf-${{ matrix.plugin }}-plugin
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ More details in the documentation.
| [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) |
| [JMS](https://github.com/springwolf/springwolf-core/tree/master/springwolf-plugins/springwolf-jms-plugin) | [JMS Example](https://github.com/springwolf/springwolf-core/tree/master/springwolf-examples/springwolf-jms-example) | ![Maven Central](https://img.shields.io/maven-central/v/io.github.springwolf/springwolf-jms?color=green&label=springwolf-jms&style=plastic) | ![Sonatype Nexus (Snapshots)](https://img.shields.io/nexus/s/io.github.springwolf/springwolf-jms?label=springwolf-jms&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) |
| [Common Model Converter](https://github.com/springwolf/springwolf-core/tree/master/springwolf-add-ons/springwolf-common-model-converters) | | ![Maven Central](https://img.shields.io/maven-central/v/io.github.springwolf/springwolf-common-model-converters?color=green&label=springwolf-common-model-converters&style=plastic) | ![Sonatype Nexus (Snapshots)](https://img.shields.io/nexus/s/io.github.springwolf/springwolf-common-model-converters?label=springwolf-common-model-converters&server=https%3A%2F%2Fs01.oss.sonatype.org&style=plastic) |
| [Generic Binding](https://github.com/springwolf/springwolf-core/tree/master/springwolf-add-ons/springwolf-generic-binding) | | ![Maven Central](https://img.shields.io/maven-central/v/io.github.springwolf/springwolf-generic-binding?color=green&label=springwolf-generic-binding&style=plastic) | ![Sonatype Nexus (Snapshots)](https://img.shields.io/nexus/s/io.github.springwolf/springwolf-generic-binding?label=springwolf-generic-binding&server=https%3A%2F%2Fs01.oss.sonatype.org&style=plastic) |
Expand Down Expand Up @@ -142,6 +143,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<td align="center" valign="top" width="14.28%"><a href="https://github.com/SheheryarAamir"><img src="https://avatars.githubusercontent.com/u/684528?v=4?s=100" width="100px;" alt="Sheheryar Aamir"/><br /><sub><b>Sheheryar Aamir</b></sub></a><br /><a href="https://github.com/stavshamir/Springwolf/commits?author=SheheryarAamir" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jmwestbe"><img src="https://avatars.githubusercontent.com/u/26258285?v=4?s=100" width="100px;" alt="jmwestbe"/><br /><sub><b>jmwestbe</b></sub></a><br /><a href="https://github.com/stavshamir/Springwolf/commits?author=jmwestbe" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/pdalfarr"><img src="https://avatars.githubusercontent.com/u/1537201?v=4?s=100" width="100px;" alt="pdalfarr"/><br /><sub><b>pdalfarr</b></sub></a><br /><a href="https://github.com/stavshamir/Springwolf/commits?author=pdalfarr" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/krzysztofxkwiecien"><img src="https://avatars.githubusercontent.com/u/37042650?v=4?s=100" width="100px;" alt="Krzysztof Kwiecień"/><br /><sub><b>Krzysztof Kwiecień</b></sub></a><br /><a href="https://github.com/stavshamir/Springwolf/commits?author=krzysztofxkwiecien" title="Code">💻</a></td>
</tr>
</tbody>
</table>
Expand Down
7 changes: 4 additions & 3 deletions RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ The following list describe the steps necessary to release a new version.
2. Run docker compose and manually test ui (or verify on website):
1. AMQP: https://amqp.demo.springwolf.dev/
2. CloudStream https://cloud-stream.demo.springwolf.dev/
3. Kafka: https://kafka.demo.springwolf.dev/
4. SNS: https://sns.demo.springwolf.dev/
5. SQS: https://sqs.demo.springwolf.dev/
3. JMS: https://jms.demo.springwolf.dev/
4. Kafka: https://kafka.demo.springwolf.dev/
5. SNS: https://sns.demo.springwolf.dev/
6. SQS: https://sqs.demo.springwolf.dev/
3. Update `all-contributors` in [README.md](README.md)
4. Remove the `-SNAPHSOT` postfix in `.env`, create a new branch `release/0.X.X` (version number), commit & push
5. Run GitHub `Publish releases` pipeline from the newly created release branch
Expand Down
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ allprojects {
project.name == 'springwolf-core' ||
project.name == 'springwolf-amqp' ||
project.name == 'springwolf-cloud-stream' ||
project.name == 'springwolf-jms' ||
project.name == 'springwolf-kafka' ||
project.name == 'springwolf-sns' ||
project.name == 'springwolf-sqs' ||
Expand Down
3 changes: 3 additions & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ include(
'springwolf-core',
'springwolf-plugins:springwolf-amqp-plugin',
'springwolf-plugins:springwolf-cloud-stream-plugin',
'springwolf-plugins:springwolf-jms-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-jms-example',
'springwolf-examples:springwolf-kafka-example',
'springwolf-examples:springwolf-sns-example',
'springwolf-examples:springwolf-sqs-example',
Expand All @@ -20,6 +22,7 @@ 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-jms-plugin').name = 'springwolf-jms'
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'
Expand Down
1 change: 1 addition & 0 deletions springwolf-examples/springwolf-jms-example/.env
6 changes: 6 additions & 0 deletions springwolf-examples/springwolf-jms-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`.
63 changes: 63 additions & 0 deletions springwolf-examples/springwolf-jms-example/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
plugins {
id 'java'

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

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

dependencies {
implementation project(":springwolf-core")
implementation project(":springwolf-add-ons:springwolf-generic-binding")
implementation project(":springwolf-plugins:springwolf-jms")

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

compileOnly "jakarta.jms:jakarta.jms-api"

implementation "org.slf4j:slf4j-api:${slf4jApiVersion}"

implementation "io.swagger.core.v3:swagger-annotations:${swaggerVersion}"

implementation "org.springframework:spring-context"
implementation "org.springframework:spring-jms"
implementation "org.springframework.boot:spring-boot"
implementation "org.springframework.boot:spring-boot-autoconfigure"
runtimeOnly "org.springframework.boot:spring-boot-starter-web"
runtimeOnly "org.springframework.boot:spring-boot-starter-artemis"

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

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

testImplementation "org.mockito:mockito-core:${mockitoCoreVersion}"

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}"
}

docker {
springBootApplication {
maintainer = 'shamir.stav@gmail.com'
baseImage = 'eclipse-temurin:17-jre-focal'
ports = [8080]
images = ["stavshamir/springwolf-jms-example:${project.version}"]
}

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

test {
dependsOn dockerBuildImage
}
20 changes: 20 additions & 0 deletions springwolf-examples/springwolf-jms-example/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
version: '3'
services:
app:
image: stavshamir/springwolf-jms-example:${SPRINGWOLF_VERSION}
links:
- activemq
environment:
BOOTSTRAP_SERVER: tcp://activemq:61616
ports:
- "8080:8080"
depends_on:
- activemq

activemq:
image: apache/activemq-artemis:2.31.2
environment:
EXTRA_ARGS: --http-host 0.0.0.0 --relax-jolokia --nio
ports:
- "61616:61616"
- "8161:8161"
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.jms;

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

@SpringBootApplication
public class SpringwolfJmsExampleApplication {

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

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.support.converter.MappingJackson2MessageConverter;
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.jms.support.converter.MessageType;

@Configuration
class ConverterConfig {

@Bean
public MessageConverter jacksonJmsMessageConverter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setTargetType(MessageType.TEXT);
converter.setTypeIdPropertyName("_type");
return converter;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// SPDX-License-Identifier: Apache-2.0
package io.github.stavshamir.springwolf.example.jms.consumers;

import io.github.stavshamir.springwolf.example.jms.dtos.AnotherPayloadDto;
import io.github.stavshamir.springwolf.example.jms.dtos.ExamplePayloadDto;
import io.github.stavshamir.springwolf.example.jms.producers.AnotherProducer;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;

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

@JmsListener(destination = "example-queue")
public void receiveExamplePayload(ExamplePayloadDto payload) {
log.info("Received new message in example-queue: {}", payload.toString());

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

anotherProducer.sendMessage(example);
}

@JmsListener(destination = "another-queue")
public void receiveAnotherPayload(AnotherPayloadDto payload) {
log.info("Received new message in another-queue: {}", 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.jms.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.jms.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,32 @@
// SPDX-License-Identifier: Apache-2.0
package io.github.stavshamir.springwolf.example.jms.producers;

import io.github.stavshamir.springwolf.addons.generic_binding.annotation.AsyncGenericOperationBinding;
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.JmsAsyncOperationBinding;
import io.github.stavshamir.springwolf.example.jms.dtos.AnotherPayloadDto;
import lombok.RequiredArgsConstructor;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Component;

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

public static final String QUEUE = "another-queue";

@AsyncPublisher(
operation =
@AsyncOperation(
channelName = QUEUE,
description = "Custom, optional description defined in the AsyncPublisher annotation"))
@JmsAsyncOperationBinding
@AsyncGenericOperationBinding(
type = "jms",
fields = {"internal-field=customValue", "nested.key=nestedValue"})
public void sendMessage(AnotherPayloadDto msg) {
template.convertAndSend(QUEUE, msg);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#########
# Spring configuration
spring.application.name=Springwolf example project - JMS


#########
# JMS configuration
spring.artemis.broker-url=${BOOTSTRAP_SERVER:tcp://localhost:61616}
spring.artemis.user=artemis
spring.artemis.password=artemis


#########
# Springwolf configuration
springwolf.enabled=true
springwolf.docket.base-package=io.github.stavshamir.springwolf.example.jms
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=example@example.com
springwolf.docket.info.contact.url=https://github.com/springwolf/springwolf-core
springwolf.docket.info.license.name=Apache License 2.0
springwolf.docket.servers.jms.protocol=jms
springwolf.docket.servers.jms.url=${spring.artemis.broker-url}
springwolf.use-fqn=true

springwolf.plugin.jms.publishing.enabled=true


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

0 comments on commit 491e1aa

Please sign in to comment.