Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(jms): JMS support #432

Merged
merged 16 commits into from
Nov 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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