Skip to content

Commit

Permalink
Feature/rsocket components Driven adapter and Entry point (#122)
Browse files Browse the repository at this point in the history
Add Rsocket driven adapter and entrypoint
  • Loading branch information
sandro30 authored Feb 25, 2021
1 parent 5c4ae31 commit b07237d
Show file tree
Hide file tree
Showing 17 changed files with 304 additions and 7 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
```

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
package=co.com.bancolombia
systemProp.version=1.8.4
systemProp.version=1.8.5
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
3 changes: 1 addition & 2 deletions src/main/java/co/com/bancolombia/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
@@ -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");
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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
}
}
Original file line number Diff line number Diff line change
@@ -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");
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
dependencies {
implementation project(':model')
implementation project(':usecase')
implementation 'org.springframework:spring-context'
compile 'org.springframework.boot:spring-boot-starter-rsocket'
}
Original file line number Diff line number Diff line change
@@ -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
}

}
Original file line number Diff line number Diff line change
@@ -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"
}
}
Original file line number Diff line number Diff line change
@@ -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<Object/* change for object response */> 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<Void> callRouteFireForget(Object objRequest/* change for object request */) {
return this.rSocketRequester
.route("route.fire.forget")
.data(objRequest)
.send()
.log();
}

// interaction model Request/Stream
public Flux<Object/* change for object response */> callRouteRequestStream() {
return this.rSocketRequester
.route("route.request.stream")
.retrieveFlux(Object.class)
.log();
}

// interaction model Channel
public Flux<Object/* change for object response */> callRouteChannel(Flux<Object/* change for object request */> objRequest) {
return this.rSocketRequester
.route("route.channel")
.data(objRequest)
.retrieveFlux(Object.class)
.log();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
dependencies {
implementation project(':model')
implementation project(':usecase')
implementation 'org.springframework:spring-context'
implementation 'org.springframework.boot:spring-boot-starter-rsocket'
}
10 changes: 10 additions & 0 deletions src/main/resources/entry-point/rsocket-responder/definition.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
Original file line number Diff line number Diff line change
@@ -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<Object/* change for object response */> getRequestResponse(Object objRequest/* change for object request */) {
// return useCase.doAction();
return Mono.empty();
}

// interaction model Request/Stream
@MessageMapping(value = "route.request.stream")
public Flux<Object/* change for object response */> getRequestStream() {
// return useCase.doAction();
return Flux.empty();
}

// interaction model Fire-and-Forget
@MessageMapping(value = "route.fire.forget")
public Mono<Void> getRequetsFireForget(Object objRequest/* change for object request */) {
// return useCase.doAction(objRequest);
return Mono.empty();
}

// interaction model Channel
@MessageMapping(value = "route.channel")
public Flux<Object/* change for object response */> getChannel(Flux<Object/* change for object request */> objRequest) {
// return useCase.doAction(objRequest);
return Flux.empty();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading

0 comments on commit b07237d

Please sign in to comment.