diff --git a/README.md b/README.md
index 296c7996..ce30afc2 100644
--- a/README.md
+++ b/README.md
@@ -28,7 +28,7 @@ To use the plugin you need Gradle version 5.6 or later, to start add the followi
```groovy
plugins {
- id "co.com.bancolombia.cleanArchitecture" version "1.8.4"
+ id "co.com.bancolombia.cleanArchitecture" version "1.8.5"
}
```
@@ -185,7 +185,9 @@ The Scaffolding Clean Architecture plugin will allow you run 8 tasks:
| asynceventbus | Async Event Bus | |
| restconsumer | Rest Client Consumer | --url [url] |
| redis | Redis | --mode [template-repository] --secret [true-false] |
+ | rsocket | Rsocket Requester | |
| r2dbc | R2dbc Postgresql Client | |
+
_**This task will generate something like that:**_
```bash
@@ -226,6 +228,7 @@ The Scaffolding Clean Architecture plugin will allow you run 8 tasks:
| generic | Empty Entry Point | --name [name] |
| restmvc | API REST (Spring Boot Starter Web) | --server [serverOption] default undertow |
| webflux | API REST (Spring Boot Starter WebFlux) | --router [true, false] default true |
+ | rsocket | Rsocket Controller Entry Point | |
Additionally, if you'll use a restmvc, you can specify the web server on which the application will run. By default, undertow.
diff --git a/gradle.properties b/gradle.properties
index 13c8be71..d46c43b1 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,2 +1,2 @@
package=co.com.bancolombia
-systemProp.version=1.8.4
+systemProp.version=1.8.5
\ No newline at end of file
diff --git a/src/functionalTest/java/co/com/bancolombia/PluginCleanFunctionalTest.java b/src/functionalTest/java/co/com/bancolombia/PluginCleanFunctionalTest.java
index bb784a3e..7f9022ee 100644
--- a/src/functionalTest/java/co/com/bancolombia/PluginCleanFunctionalTest.java
+++ b/src/functionalTest/java/co/com/bancolombia/PluginCleanFunctionalTest.java
@@ -259,6 +259,37 @@ public void canRunTaskGenerateDrivenAdapterRestConsumerCaseWithParameters() {
assertEquals(result.task(":" + task).getOutcome(), TaskOutcome.SUCCESS);
}
+ @Test
+ public void canRunTaskGenerateDrivenAdapterRsocketRequesterCase() {
+ canRunTaskGenerateStructureReactiveProject();
+ String task = "generateDrivenAdapter";
+ String valueDrivenAdapter = "rsocket";
+
+ runner.withArguments(task, "--type=" + valueDrivenAdapter);
+ runner.withProjectDir(projectDir);
+ BuildResult result = runner.build();
+ assertTrue(new File("build/functionalTest/infrastructure/driven-adapters/rsocket-requester/build.gradle").exists());
+ assertTrue(new File("build/functionalTest/applications/app-service/src/main/java/co/com/bancolombia/config/RequesterConfig.java").exists());
+ assertTrue(new File("build/functionalTest/infrastructure/driven-adapters/rsocket-requester/src/main/java/co/com/bancolombia/service/RsocketAdapter.java").exists());
+ assertTrue(new File("build/functionalTest/infrastructure/driven-adapters/rsocket-requester/src/test/java/co/com/bancolombia/service").exists());
+ assertEquals(result.task(":" + task).getOutcome(), TaskOutcome.SUCCESS);
+ }
+
+ @Test
+ public void canRunTaskGenerateEntryPointrRsocketResponderCase() {
+ canRunTaskGenerateStructureReactiveProject();
+ String task = "generateEntryPoint";
+ String valueDrivenAdapter = "rsocket";
+
+ runner.withArguments(task, "--type=" + valueDrivenAdapter);
+ runner.withProjectDir(projectDir);
+ BuildResult result = runner.build();
+ assertTrue(new File("build/functionalTest/infrastructure/entry-points/rsocket-responder/build.gradle").exists());
+ assertTrue(new File("build/functionalTest/infrastructure/entry-points/rsocket-responder/src/main/java/co/com/bancolombia/controller/RsocketController.java").exists());
+ assertTrue(new File("build/functionalTest/infrastructure/entry-points/rsocket-responder/src/test/java/co/com/bancolombia/controller").exists());
+ assertEquals(result.task(":" + task).getOutcome(), TaskOutcome.SUCCESS);
+ }
+
@Test
public void canRunTaskGenerateEntryPointCaseWithParameters() {
canRunTaskGenerateStructureWithOutParameters();
diff --git a/src/main/java/co/com/bancolombia/Constants.java b/src/main/java/co/com/bancolombia/Constants.java
index f14ae24f..1e2a2c4a 100644
--- a/src/main/java/co/com/bancolombia/Constants.java
+++ b/src/main/java/co/com/bancolombia/Constants.java
@@ -16,8 +16,7 @@ public class Constants {
public static final String SECRETS_VERSION = "2.1.0";
public static final String RCOMMONS_ASYNC_COMMONS_STARTER_VERSION = "0.4.7";
public static final String RCOMMONS_OBJECT_MAPPER_VERSION = "0.1.0";
- public static final String PLUGIN_VERSION = "1.8.4";
-
+ public static final String PLUGIN_VERSION = "1.8.5";
public static final String TOMCAT_EXCLUSION = "compile.exclude group: \"org.springframework.boot\", module:\"spring-boot-starter-tomcat\"";
public enum BooleanOption {
diff --git a/src/main/java/co/com/bancolombia/factory/adapters/DrivenAdapterRsocketRequester.java b/src/main/java/co/com/bancolombia/factory/adapters/DrivenAdapterRsocketRequester.java
new file mode 100644
index 00000000..a6303090
--- /dev/null
+++ b/src/main/java/co/com/bancolombia/factory/adapters/DrivenAdapterRsocketRequester.java
@@ -0,0 +1,25 @@
+package co.com.bancolombia.factory.adapters;
+
+import co.com.bancolombia.exceptions.CleanException;
+import co.com.bancolombia.exceptions.InvalidTaskOptionException;
+import co.com.bancolombia.factory.ModuleBuilder;
+import co.com.bancolombia.factory.ModuleFactory;
+
+import java.io.IOException;
+
+public class DrivenAdapterRsocketRequester implements ModuleFactory {
+
+ @Override
+ public void buildModule(ModuleBuilder builder) throws IOException, CleanException {
+ builder.loadPackage();
+ if (builder.isReactive()) {
+ builder.appendToSettings("rsocket-requester", "infrastructure/driven-adapters");
+ builder.appendDependencyToModule("app-service",
+ "implementation project(':rsocket-requester')");
+ builder.setupFromTemplate("driven-adapter/rsocket-requester");
+ } else {
+ throw new InvalidTaskOptionException("Rsocket requester Driven Adapter is only available in reactive projects");
+ }
+
+ }
+}
diff --git a/src/main/java/co/com/bancolombia/factory/adapters/ModuleFactoryDrivenAdapter.java b/src/main/java/co/com/bancolombia/factory/adapters/ModuleFactoryDrivenAdapter.java
index fb26168a..f9b28583 100644
--- a/src/main/java/co/com/bancolombia/factory/adapters/ModuleFactoryDrivenAdapter.java
+++ b/src/main/java/co/com/bancolombia/factory/adapters/ModuleFactoryDrivenAdapter.java
@@ -19,6 +19,8 @@ public static ModuleFactory getDrivenAdapterFactory(DrivenAdapterType type) thro
return new DrivenAdapterRestConsumer();
case REDIS:
return new DrivenAdapterRedis();
+ case RSOCKET:
+ return new DrivenAdapterRsocketRequester();
case R2DBC:
return new DrivenAdapterR2dbcPostgreSQL();
default:
@@ -27,6 +29,6 @@ public static ModuleFactory getDrivenAdapterFactory(DrivenAdapterType type) thro
}
public enum DrivenAdapterType {
- JPA, MONGODB, ASYNCEVENTBUS, GENERIC, RESTCONSUMER, REDIS, R2DBC
+ JPA, MONGODB, ASYNCEVENTBUS, GENERIC, RESTCONSUMER, REDIS, RSOCKET, R2DBC
}
}
diff --git a/src/main/java/co/com/bancolombia/factory/entrypoints/EntryPointRsocketResponder.java b/src/main/java/co/com/bancolombia/factory/entrypoints/EntryPointRsocketResponder.java
new file mode 100644
index 00000000..3dcf01fb
--- /dev/null
+++ b/src/main/java/co/com/bancolombia/factory/entrypoints/EntryPointRsocketResponder.java
@@ -0,0 +1,28 @@
+package co.com.bancolombia.factory.entrypoints;
+
+import co.com.bancolombia.exceptions.CleanException;
+import co.com.bancolombia.exceptions.InvalidTaskOptionException;
+import co.com.bancolombia.factory.ModuleBuilder;
+import co.com.bancolombia.factory.ModuleFactory;
+
+import java.io.IOException;
+
+public class EntryPointRsocketResponder implements ModuleFactory {
+
+ @Override
+ public void buildModule(ModuleBuilder builder) throws IOException, CleanException {
+ builder.loadPackage();
+ if (builder.isReactive()) {
+ builder.appendToSettings("rsocket-responder", "infrastructure/entry-points");
+ builder.appendToProperties("spring.rsocket.server")
+ .put("port", 7000);
+ builder.appendDependencyToModule("app-service",
+ "implementation project(':rsocket-responder')");
+ builder.setupFromTemplate("entry-point/rsocket-responder");
+ } else {
+ throw new InvalidTaskOptionException("Rsocket responder Entry Point is only available in reactive projects");
+ }
+
+ }
+
+}
diff --git a/src/main/java/co/com/bancolombia/factory/entrypoints/ModuleFactoryEntryPoint.java b/src/main/java/co/com/bancolombia/factory/entrypoints/ModuleFactoryEntryPoint.java
index 5b6dfb95..f0f28e2f 100644
--- a/src/main/java/co/com/bancolombia/factory/entrypoints/ModuleFactoryEntryPoint.java
+++ b/src/main/java/co/com/bancolombia/factory/entrypoints/ModuleFactoryEntryPoint.java
@@ -13,12 +13,14 @@ public static ModuleFactory getEntryPointFactory(EntryPointType type) throws Inv
return new EntryPointRestWebflux();
case GENERIC:
return new EntryPointGeneric();
+ case RSOCKET:
+ return new EntryPointRsocketResponder();
default:
throw new InvalidTaskOptionException("Entry Point type invalid");
}
}
public enum EntryPointType {
- RESTMVC, WEBFLUX, GENERIC
+ RESTMVC, WEBFLUX, GENERIC, RSOCKET
}
}
diff --git a/src/main/resources/driven-adapter/rsocket-requester/build.gradle.mustache b/src/main/resources/driven-adapter/rsocket-requester/build.gradle.mustache
new file mode 100644
index 00000000..72c8dd09
--- /dev/null
+++ b/src/main/resources/driven-adapter/rsocket-requester/build.gradle.mustache
@@ -0,0 +1,6 @@
+dependencies {
+ implementation project(':model')
+ implementation project(':usecase')
+ implementation 'org.springframework:spring-context'
+ compile 'org.springframework.boot:spring-boot-starter-rsocket'
+}
\ No newline at end of file
diff --git a/src/main/resources/driven-adapter/rsocket-requester/config/requester-config.java.mustache b/src/main/resources/driven-adapter/rsocket-requester/config/requester-config.java.mustache
new file mode 100644
index 00000000..2e2e95bc
--- /dev/null
+++ b/src/main/resources/driven-adapter/rsocket-requester/config/requester-config.java.mustache
@@ -0,0 +1,26 @@
+package {{package}}.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.MediaType;
+import org.springframework.http.codec.cbor.Jackson2CborDecoder;
+import org.springframework.http.codec.cbor.Jackson2CborEncoder;
+import org.springframework.messaging.rsocket.RSocketRequester;
+import org.springframework.messaging.rsocket.RSocketStrategies;
+
+@Configuration
+public class RequesterConfig {
+
+ @Bean
+ public RSocketRequester rSocketRequester(RSocketStrategies rSocketStrategies) {
+ RSocketStrategies strategies = RSocketStrategies.builder()
+ .encoders(encoders -> encoders.add(new Jackson2CborEncoder()))
+ .decoders(decoders -> decoders.add(new Jackson2CborDecoder()))
+ .build();
+ return RSocketRequester.builder()
+ .rsocketStrategies(strategies)
+ .dataMimeType(MediaType.APPLICATION_CBOR)
+ .tcp("localhost",7000); // server IP or DNS, and port
+ }
+
+}
diff --git a/src/main/resources/driven-adapter/rsocket-requester/definition.json b/src/main/resources/driven-adapter/rsocket-requester/definition.json
new file mode 100644
index 00000000..faab4019
--- /dev/null
+++ b/src/main/resources/driven-adapter/rsocket-requester/definition.json
@@ -0,0 +1,11 @@
+{
+ "folders": [
+ "infrastructure/driven-adapters/rsocket-requester/src/main/java/{{packagePath}}/service",
+ "infrastructure/driven-adapters/rsocket-requester/src/test/java/{{packagePath}}/service"
+ ],
+ "files": {
+ "driven-adapter/rsocket-requester/config/requester-config.java.mustache": "applications/app-service/src/main/java/{{packagePath}}/config/RequesterConfig.java",
+ "driven-adapter/rsocket-requester/build.gradle.mustache": "infrastructure/driven-adapters/rsocket-requester/build.gradle",
+ "driven-adapter/rsocket-requester/rsocket-requester.java.mustache": "infrastructure/driven-adapters/rsocket-requester/src/main/java/{{packagePath}}/service/RsocketAdapter.java"
+ }
+}
diff --git a/src/main/resources/driven-adapter/rsocket-requester/rsocket-requester.java.mustache b/src/main/resources/driven-adapter/rsocket-requester/rsocket-requester.java.mustache
new file mode 100644
index 00000000..01f55e25
--- /dev/null
+++ b/src/main/resources/driven-adapter/rsocket-requester/rsocket-requester.java.mustache
@@ -0,0 +1,60 @@
+package {{package}}.service;
+
+{{#lombok}}
+import lombok.RequiredArgsConstructor;
+{{/lombok}}
+import org.springframework.stereotype.Service;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+import org.springframework.messaging.rsocket.RSocketRequester;
+
+@Service
+{{#lombok}}
+@RequiredArgsConstructor
+{{/lombok}}
+public class RsocketAdapter // implements Gateway from domain
+{
+
+ private final RSocketRequester rSocketRequester;
+ {{^lombok}}
+
+ public RsocketAdapter(RSocketRequester rSocketRequester) {
+ this.rSocketRequester = rSocketRequester;
+ }
+ {{/lombok}}
+
+ // interaction model Request/Response
+ public Mono callRouteRequest(Object objRequest/* change for object request */) {
+ return this.rSocketRequester
+ .route("route.request.response")
+ .data(objRequest)
+ .retrieveMono(Object.class)
+ .log();
+ }
+
+ // interaction model Fire-and-Forget
+ public Mono callRouteFireForget(Object objRequest/* change for object request */) {
+ return this.rSocketRequester
+ .route("route.fire.forget")
+ .data(objRequest)
+ .send()
+ .log();
+ }
+
+ // interaction model Request/Stream
+ public Flux callRouteRequestStream() {
+ return this.rSocketRequester
+ .route("route.request.stream")
+ .retrieveFlux(Object.class)
+ .log();
+ }
+
+ // interaction model Channel
+ public Flux callRouteChannel(Flux objRequest) {
+ return this.rSocketRequester
+ .route("route.channel")
+ .data(objRequest)
+ .retrieveFlux(Object.class)
+ .log();
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/entry-point/rsocket-responder/build.gradle.mustache b/src/main/resources/entry-point/rsocket-responder/build.gradle.mustache
new file mode 100644
index 00000000..25fcd608
--- /dev/null
+++ b/src/main/resources/entry-point/rsocket-responder/build.gradle.mustache
@@ -0,0 +1,6 @@
+dependencies {
+ implementation project(':model')
+ implementation project(':usecase')
+ implementation 'org.springframework:spring-context'
+ implementation 'org.springframework.boot:spring-boot-starter-rsocket'
+}
diff --git a/src/main/resources/entry-point/rsocket-responder/definition.json b/src/main/resources/entry-point/rsocket-responder/definition.json
new file mode 100644
index 00000000..a8ca2171
--- /dev/null
+++ b/src/main/resources/entry-point/rsocket-responder/definition.json
@@ -0,0 +1,10 @@
+{
+ "folders": [
+ "infrastructure/entry-points/rsocket-responder/src/main/java/{{packagePath}}/controller",
+ "infrastructure/entry-points/rsocket-responder/src/test/java/{{packagePath}}/controller"
+ ],
+ "files": {
+ "entry-point/rsocket-responder/build.gradle.mustache": "infrastructure/entry-points/rsocket-responder/build.gradle",
+ "entry-point/rsocket-responder/rsocket-responder.java.mustache": "infrastructure/entry-points/rsocket-responder/src/main/java/{{packagePath}}/controller/RsocketController.java"
+ }
+}
diff --git a/src/main/resources/entry-point/rsocket-responder/rsocket-responder.java.mustache b/src/main/resources/entry-point/rsocket-responder/rsocket-responder.java.mustache
new file mode 100644
index 00000000..459acaf8
--- /dev/null
+++ b/src/main/resources/entry-point/rsocket-responder/rsocket-responder.java.mustache
@@ -0,0 +1,53 @@
+package {{package}}.controller;
+
+{{#lombok}}
+import lombok.RequiredArgsConstructor;
+{{/lombok}}
+import org.springframework.messaging.handler.annotation.MessageMapping;
+import org.springframework.stereotype.Controller;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+@Controller
+{{#lombok}}
+@RequiredArgsConstructor
+{{/lombok}}
+public class RsocketController {
+
+ // private final MyUseCase useCase;
+{{^lombok}}
+
+ /*public RsocketController(MyUseCase useCase) {
+ this.useCase = useCase;
+ }*/
+{{/lombok}}
+
+ // interaction model Request/Response
+ @MessageMapping(value = "route.request.response")
+ public Mono getRequestResponse(Object objRequest/* change for object request */) {
+ // return useCase.doAction();
+ return Mono.empty();
+ }
+
+ // interaction model Request/Stream
+ @MessageMapping(value = "route.request.stream")
+ public Flux getRequestStream() {
+ // return useCase.doAction();
+ return Flux.empty();
+ }
+
+ // interaction model Fire-and-Forget
+ @MessageMapping(value = "route.fire.forget")
+ public Mono getRequetsFireForget(Object objRequest/* change for object request */) {
+ // return useCase.doAction(objRequest);
+ return Mono.empty();
+ }
+
+ // interaction model Channel
+ @MessageMapping(value = "route.channel")
+ public Flux getChannel(Flux objRequest) {
+ // return useCase.doAction(objRequest);
+ return Flux.empty();
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/co/com/bancolombia/task/GenerateDrivenAdapterTaskTest.java b/src/test/java/co/com/bancolombia/task/GenerateDrivenAdapterTaskTest.java
index b867aa6e..20608c46 100644
--- a/src/test/java/co/com/bancolombia/task/GenerateDrivenAdapterTaskTest.java
+++ b/src/test/java/co/com/bancolombia/task/GenerateDrivenAdapterTaskTest.java
@@ -100,6 +100,20 @@ public void generateRestConsumer() throws IOException, CleanException {
assertTrue(new File("build/unitTest/applications/app-service/src/main/java/co/com/bancolombia/config/RestConsumerConfig.java").exists());
}
+ @Test
+ public void generateRsocketRequester() throws IOException, CleanException {
+ // Arrange
+ setup(GenerateStructureTask.ProjectType.REACTIVE);
+ task.setType(ModuleFactoryDrivenAdapter.DrivenAdapterType.RSOCKET);
+ // Act
+ task.generateDrivenAdapterTask();
+ // Assert
+ assertTrue(new File("build/unitTest/infrastructure/driven-adapters/rsocket-requester/build.gradle").exists());
+ assertTrue(new File("build/unitTest/applications/app-service/src/main/java/co/com/bancolombia/config/RequesterConfig.java").exists());
+ assertTrue(new File("build/unitTest/infrastructure/driven-adapters/rsocket-requester/src/main/java/co/com/bancolombia/service/RsocketAdapter.java").exists());
+ assertTrue(new File("build/unitTest/infrastructure/driven-adapters/rsocket-requester/src/test/java/co/com/bancolombia/service").exists());
+ }
+
@Test
public void generateDrivenAdapterJPARepository() throws IOException, CleanException {
// Arrange
diff --git a/src/test/java/co/com/bancolombia/task/GenerateEntryPointTaskTest.java b/src/test/java/co/com/bancolombia/task/GenerateEntryPointTaskTest.java
index 2f5e288b..a3acad38 100644
--- a/src/test/java/co/com/bancolombia/task/GenerateEntryPointTaskTest.java
+++ b/src/test/java/co/com/bancolombia/task/GenerateEntryPointTaskTest.java
@@ -27,11 +27,16 @@ public class GenerateEntryPointTaskTest {
private GenerateEntryPointTask task;
@Before
- public void setup() throws IOException, CleanException {
+ public void init() throws IOException, CleanException {
+ setup(GenerateStructureTask.ProjectType.IMPERATIVE);
+ }
+
+ public void setup(GenerateStructureTask.ProjectType type) throws IOException, CleanException {
Project project = ProjectBuilder.builder().withProjectDir(new File("build/unitTest")).build();
deleteStructure(project.getProjectDir().toPath());
project.getTasks().create("ca", GenerateStructureTask.class);
GenerateStructureTask caTask = (GenerateStructureTask) project.getTasks().getByName("ca");
+ caTask.setType(type);
caTask.generateStructureTask();
ProjectBuilder.builder()
@@ -106,6 +111,19 @@ public void generateEntryPointGeneric() throws IOException, CleanException {
assertTrue(new File("build/unitTest/infrastructure/entry-points/my-entry-point/src/test/java/co/com/bancolombia/myentrypoint").exists());
}
+ @Test
+ public void generateEntryPointRsocketResponder() throws IOException, CleanException {
+ // Arrange
+ setup(GenerateStructureTask.ProjectType.REACTIVE);
+ task.setType(ModuleFactoryEntryPoint.EntryPointType.RSOCKET);
+ // Act
+ task.generateEntryPointTask();
+ // Assert
+ assertTrue(new File("build/unitTest/infrastructure/entry-points/rsocket-responder/build.gradle").exists());
+ assertTrue(new File("build/unitTest/infrastructure/entry-points/rsocket-responder/src/main/java/co/com/bancolombia/controller/RsocketController.java").exists());
+ assertTrue(new File("build/unitTest/infrastructure/entry-points/rsocket-responder/src/test/java/co/com/bancolombia/controller").exists());
+ }
+
@Test
public void generateEntryPointApiRestWithDefaultServer() throws IOException, CleanException {
// Arrange
@@ -173,6 +191,7 @@ public void generateEntryPointApiRestWithTomcatServer() throws IOException, Clea
@Test
public void generateEntryPointReactiveWebWithoutRouterFunctions() throws IOException, CleanException {
// Arrange
+ setup(GenerateStructureTask.ProjectType.REACTIVE);
task.setType(ModuleFactoryEntryPoint.EntryPointType.WEBFLUX);
task.setRouter(Constants.BooleanOption.FALSE);
// Act
@@ -187,6 +206,7 @@ public void generateEntryPointReactiveWebWithoutRouterFunctions() throws IOExcep
@Test
public void generateEntryPointReactiveWebWithRouterFunctions() throws IOException, CleanException {
// Arrange
+ setup(GenerateStructureTask.ProjectType.REACTIVE);
task.setType(ModuleFactoryEntryPoint.EntryPointType.WEBFLUX);
task.setRouter(Constants.BooleanOption.TRUE);
@@ -201,6 +221,7 @@ public void generateEntryPointReactiveWebWithRouterFunctions() throws IOExceptio
@Test
public void generateEntryPointReactiveWebWithDefaultOptionFunctions() throws IOException, CleanException {
// Arrange
+ setup(GenerateStructureTask.ProjectType.REACTIVE);
task.setType(ModuleFactoryEntryPoint.EntryPointType.WEBFLUX);
// Act