Skip to content

Commit

Permalink
feat(generic-binding): Move @AsyncGenericOperationBinding to own addon
Browse files Browse the repository at this point in the history
  • Loading branch information
timonback committed Oct 8, 2023
1 parent b762bfc commit 832d575
Show file tree
Hide file tree
Showing 16 changed files with 190 additions and 129 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: springwolf-common-model-converters
name: springwolf-addons

on:
push:
Expand All @@ -7,14 +7,18 @@ on:
pull_request:
types: [ opened, synchronize, ready_for_review ]

env:
addon: springwolf-add-ons/springwolf-common-model-converters

jobs:
build:

runs-on: ubuntu-latest

strategy:
matrix:
addon: [ "common-model-converters", "generic-binding" ]

env:
addon: springwolf-add-ons/springwolf-${{ matrix.addon }}

steps:
- uses: actions/checkout@v4

Expand Down
3 changes: 2 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ allprojects {
project.name == 'springwolf-kafka' ||
project.name == 'springwolf-sqs' ||
project.name == 'springwolf-ui' ||
project.name == 'springwolf-common-model-converters')
project.name == 'springwolf-common-model-converters' ||
project.name == 'springwolf-generic-binding')
tasks.withType(PublishToMavenRepository).configureEach { it.enabled = publishingEnabled }
tasks.withType(PublishToMavenLocal).configureEach { it.enabled = publishingEnabled }
publishing {
Expand Down
3 changes: 2 additions & 1 deletion settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ include(
'springwolf-examples:springwolf-kafka-example',
'springwolf-examples:springwolf-sqs-example',
'springwolf-ui',
'springwolf-add-ons:springwolf-common-model-converters'
'springwolf-add-ons:springwolf-common-model-converters',
'springwolf-add-ons:springwolf-generic-binding'
)

project(':springwolf-plugins:springwolf-amqp-plugin').name = 'springwolf-amqp'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ Add the following dependency:

```groovy
dependencies {
implementation 'io.github.springwolf:springwolf-common-model-converters:0.1.1'
implementation 'io.github.springwolf:springwolf-common-model-converters:<springwolf-version>'
}
```
Empty file.
Empty file.
45 changes: 45 additions & 0 deletions springwolf-add-ons/springwolf-generic-binding/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Springwolf Generic Binding Add-on

### Table Of Contents

- [About](#about)
- [Usage](#usage)
- [Dependencies](#dependencies)
- [Code](#code)

### About

This module allows to document any binding in a generic way.

It is intended to document fields that are not yet support by Springwolf and/or AsyncApi.
It can also be used to document vendor-specific protocols or properties.

There exists no validation on key or value names.

### Usage

Add the following dependency:

#### Dependencies

```groovy
dependencies {
implementation 'io.github.springwolf:springwolf-generic-binding:0.1.1'
}
```

#### Code

```java
class TestClass {
@AsyncPublisher(
// ...
)
@AsyncGenericOperationBinding(
type = "custom-sqs",
fields = {"internal-field=customValue", "nested.key=nestedValue"})
public void sendMessage(AnotherPayloadDto msg) {
// ...
}
}
```
51 changes: 51 additions & 0 deletions springwolf-add-ons/springwolf-generic-binding/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
plugins {
id 'java-library'

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

dependencies {
api project(":springwolf-core")

implementation "com.asyncapi:asyncapi-core:${asyncapiCoreVersion}"
implementation "org.slf4j:slf4j-api:${slf4jApiVersion}"

implementation "org.springframework:spring-context"
implementation "org.springframework:spring-core"

annotationProcessor "org.projectlombok:lombok:${lombokVersion}"

testImplementation "org.assertj:assertj-core:${assertjCoreVersion}"
testImplementation "org.junit.jupiter:junit-jupiter-api:${junitJupiterVersion}"
testRuntimeOnly "org.junit.jupiter:junit-jupiter:${junitJupiterVersion}"
}

jar {
enabled = true
archiveClassifier = ''
}
bootJar.enabled = false

java {
withJavadocJar()
withSourcesJar()
}

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

useJUnitPlatform()
}

publishing {
publications {
mavenJava(MavenPublication) {
pom {
name = 'springwolf-generic-binding'
description = 'Document any AsyncApi binding in Springwolf using a generic way'
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: Apache-2.0
package io.github.stavshamir.springwolf.asyncapi.scanners.bindings.annotation;
package io.github.stavshamir.springwolf.asyncapi.addon.genericbinding.annotation;

import io.github.stavshamir.springwolf.asyncapi.scanners.channels.annotation.AsyncOperationBinding;

Expand All @@ -8,8 +8,6 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

// TODO: move classes to new bindings package

/**
* Springwolf cannot support all available protocol bindings that exist.
* To allow users to manually define them, {@link AsyncGenericOperationBinding} can be used.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// SPDX-License-Identifier: Apache-2.0
package io.github.stavshamir.springwolf.asyncapi.scanners.bindings.annotation.processor;
package io.github.stavshamir.springwolf.asyncapi.addon.genericbinding.annotation.processor;

import com.asyncapi.v2.binding.operation.OperationBinding;
import io.github.stavshamir.springwolf.asyncapi.addon.genericbinding.annotation.AsyncGenericOperationBinding;
import io.github.stavshamir.springwolf.asyncapi.scanners.bindings.BindingProcessorPriority;
import io.github.stavshamir.springwolf.asyncapi.scanners.bindings.ProcessedOperationBinding;
import io.github.stavshamir.springwolf.asyncapi.scanners.bindings.annotation.AsyncGenericOperationBinding;
import io.github.stavshamir.springwolf.asyncapi.scanners.bindings.processor.AbstractOperationBindingProcessor;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: Apache-2.0
package io.github.stavshamir.springwolf.asyncapi.scanners.bindings.annotation.processor;
package io.github.stavshamir.springwolf.asyncapi.addon.genericbinding.annotation.processor;

import lombok.extern.slf4j.Slf4j;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
package io.github.stavshamir.springwolf.asyncapi.scanners.bindings.annotation.processor;
package io.github.stavshamir.springwolf.asyncapi.addon.genericbinding.annotation.processor;

import io.github.stavshamir.springwolf.asyncapi.scanners.bindings.annotation.AsyncGenericOperationBinding;
import io.github.stavshamir.springwolf.asyncapi.addon.genericbinding.annotation.AsyncGenericOperationBinding;
import io.github.stavshamir.springwolf.asyncapi.scanners.bindings.ProcessedOperationBinding;
import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -39,27 +39,6 @@ void testClassWithAnnotationHasABinding() {
assertThat(binding.getExtensionFields()).isEqualTo(Map.of("binding", Map.of("field", "1"), "field", "true"));
}

@Test
void testClassWithMultipleAnnotationHasABinding() {
// when
List<ProcessedOperationBinding> result = getProcessedOperationBindings(ClassWithMultipleAnnotation.class);

// then
assertThat(result).hasSize(2);

ProcessedOperationBinding processedOperationBinding = result.get(0);
assertThat(processedOperationBinding.getType()).isEqualTo("test-binding");
AsyncGenericOperationBindingProcessor.DefaultAsyncGenerialOperationBinding binding =
(AsyncGenericOperationBindingProcessor.DefaultAsyncGenerialOperationBinding)
processedOperationBinding.getBinding();
assertThat(binding.getExtensionFields()).isEqualTo(Map.of("binding", Map.of("field", "1"), "field", "true"));

ProcessedOperationBinding processedOperationBinding2 = result.get(1);
assertThat(processedOperationBinding2.getType()).isEqualTo("another-binding");
assertThat(processedOperationBinding2.getBinding())
.isEqualTo(new AsyncGenericOperationBindingProcessor.DefaultAsyncGenerialOperationBinding(Map.of()));
}

private List<ProcessedOperationBinding> getProcessedOperationBindings(Class<?> testClass) {
List<ProcessedOperationBinding> result = Arrays.stream(testClass.getDeclaredMethods())
.map((m) -> m.getAnnotationsByType(AsyncGenericOperationBinding.class))
Expand All @@ -82,13 +61,78 @@ private void methodWithAnnotation() {}
private void methodWithoutAnnotation() {}
}

private static class ClassWithMultipleAnnotation {
@AsyncGenericOperationBinding(
type = "test-binding",
fields = {"binding.field=1", "field=true"})
@AsyncGenericOperationBinding(type = "another-binding")
private void methodWithAnnotation() {}
static class PropertiesUtilTest {

private void methodWithoutAnnotation() {}
@Test
void emptyTest() {
// given
String[] strings = {};

// when
Map<String, Object> result = PropertiesUtil.toMap(strings);

// then
assertThat(result).isEmpty();
}

@Test
void onePropertyTest() {
// given
String[] strings = {"key=value"};

// when
Map<String, Object> result = PropertiesUtil.toMap(strings);

// then
assertThat(result).isEqualTo(Map.of("key", "value"));
}

@Test
void twoPropertiesTest() {
// given
String[] strings = {"key1=value1", "key2=value2"};

// when
Map<String, Object> result = PropertiesUtil.toMap(strings);

// then
assertThat(result).isEqualTo(Map.of("key1", "value1", "key2", "value2"));
}

@Test
void nestedPropertyTest() {
// given
String[] strings = {"nested.key=value"};

// when
Map<String, Object> result = PropertiesUtil.toMap(strings);

// then
assertThat(result).isEqualTo(Map.of("nested", Map.of("key", "value")));
}

@Test
void deeplyNestedPropertyTest() {
// given
String[] strings = {"very.deeply.nested.key=value"};

// when
Map<String, Object> result = PropertiesUtil.toMap(strings);

// then
assertThat(result).isEqualTo(Map.of("very", Map.of("deeply", Map.of("nested", Map.of("key", "value")))));
}

@Test
void yamlSyntaxDoesWorkAsWell() {
// given
String[] strings = {"key: value"};

// when
Map<String, Object> result = PropertiesUtil.toMap(strings);

// then
assertThat(result).isEqualTo(Map.of("key", "value"));
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
package io.github.stavshamir.springwolf.asyncapi.scanners.bindings;

import io.github.stavshamir.springwolf.asyncapi.scanners.bindings.annotation.AsyncGenericOperationBinding;
import io.github.stavshamir.springwolf.configuration.AsyncApiDocket;

/**
Expand All @@ -20,7 +19,7 @@ public class BindingProcessorPriority {
* <p>
* to extend and overwrite the protocol binding - which might not support all features
* <p>
* Example: {@link AsyncGenericOperationBinding}
* Example: AsyncGenericOperationBinding
*/
public static final int GENERIC_BINDING = 2;

Expand Down
Loading

0 comments on commit 832d575

Please sign in to comment.