[JAVA-13854] Half list moved (#12598)
* [JAVA-13854] added parent module * [JAVA-13854] moved apache-tapestry(submodule) to web-modules(parent) * [JAVA-13854] moved bootique(submodule) to web-modules(parent) * [JAVA-13854] moved dropwizard(submodule) to web-modules(parent) * [JAVA-13854] moved blade(submodule) to web-modules(parent) * [JAVA-13854] moved java-lite(submodule) to web-modules(parent) * [JAVA-13854] moved jooby(submodule) to web-modules(parent) * [JAVA-13854] moved linkrest(submodule) to web-modules(parent) * [JAVA-13854] moved ninja(submodule) to web-modules(parent) * [JAVA-13854] moved ratpack(submodule) to web-modules(parent) * [JAVA-13854] moved resteasy(submodule) to web-modules(parent) * [JAVA-13854] moved restx(submodule) to web-modules(parent) * [JAVA-13854] moved spark-java(submodule) to web-modules(parent) * [JAVA-13854] moved vraptor(submodule) to web-modules(parent) * [JAVA-13854] delete modules that were moved * [JAVA-13854] * [JAVA-13854] * [JAVA-13854] delete ninja submodule + moved raml(submodule) to web-modules(parent) * [JAVA-13854] moved gwt(submodule) to web-modules(parent) * [JAVA-13854] moved jakarta-ee(submodule) to web-modules(parent) * [JAVA-13854] moved javax-servlets(submodule) to web-modules(parent) * [JAVA-13854] moved javax-servlets-2(submodule) to web-modules(parent) * [JAVA-13854] moved jee-7(submodule) to web-modules(parent) * [JAVA-13854] moved play-framework(not a module) to web-modules * [JAVA-13854] fix failing test * [JAVA-13854] moved struts-2(submodule) to web-modules(parent) * [JAVA-13854] moved wicket(submodule) to web-modules(parent) * [JAVA-13854] deleted modules that were moved to web-modules * JAVA-13854 Removed moved modules from the main pom.xml Co-authored-by: panagiotiskakos <panagiotis.kakos@libra-is.com> Co-authored-by: Dhawal Kapil <dhawalkapil@gmail.com>
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
## Ratpack
|
||||
|
||||
This module contains articles about Ratpack.
|
||||
|
||||
### Relevant articles
|
||||
|
||||
- [Introduction to Ratpack](https://www.baeldung.com/ratpack)
|
||||
- [Ratpack Google Guice Integration](https://www.baeldung.com/ratpack-google-guice)
|
||||
- [Ratpack Integration with Spring Boot](http://www.baeldung.com/ratpack-spring-boot)
|
||||
- [Ratpack with Hystrix](https://www.baeldung.com/ratpack-hystrix)
|
||||
- [Ratpack HTTP Client](https://www.baeldung.com/ratpack-http-client)
|
||||
- [Ratpack with RxJava](https://www.baeldung.com/ratpack-rxjava)
|
||||
- [Ratpack with Groovy](https://www.baeldung.com/ratpack-groovy)
|
||||
- [Reactive Streams API with Ratpack](https://www.baeldung.com/ratpack-reactive-streams-api)
|
||||
@@ -0,0 +1,37 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath "io.ratpack:ratpack-gradle:1.5.4"
|
||||
classpath "com.h2database:h2:1.4.193"
|
||||
}
|
||||
}
|
||||
|
||||
if (!JavaVersion.current().java8Compatible) {
|
||||
throw new IllegalStateException("Must be built with Java 8 or higher")
|
||||
}
|
||||
|
||||
apply plugin: "io.ratpack.ratpack-java"
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'groovy'
|
||||
apply plugin: 'io.ratpack.ratpack-groovy'
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile ratpack.dependency('hikari')
|
||||
compile 'com.h2database:h2:1.4.193'
|
||||
testCompile 'junit:junit:4.11'
|
||||
runtime "org.slf4j:slf4j-simple:1.7.21"
|
||||
}
|
||||
|
||||
test {
|
||||
testLogging {
|
||||
events 'started', 'passed'
|
||||
}
|
||||
}
|
||||
|
||||
mainClassName = "com.baeldung.Application"
|
||||
@@ -0,0 +1,97 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>ratpack</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<name>ratpack</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>web-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.ratpack</groupId>
|
||||
<artifactId>ratpack-spring-boot-starter</artifactId>
|
||||
<version>${ratpack.version}</version>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.ratpack</groupId>
|
||||
<artifactId>ratpack-core</artifactId>
|
||||
<version>${ratpack.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-sql</artifactId>
|
||||
<version>${groovy.sql.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.ratpack</groupId>
|
||||
<artifactId>ratpack-hikari</artifactId>
|
||||
<version>${ratpack.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.ratpack</groupId>
|
||||
<artifactId>ratpack-groovy-test</artifactId>
|
||||
<version>${ratpack.test.latest.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.ratpack</groupId>
|
||||
<artifactId>ratpack-hystrix</artifactId>
|
||||
<version>${ratpack.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.netflix.hystrix</groupId>
|
||||
<artifactId>hystrix-core</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.hystrix</groupId>
|
||||
<artifactId>hystrix-core</artifactId>
|
||||
<version>${hystrix.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.ratpack</groupId>
|
||||
<artifactId>ratpack-rx</artifactId>
|
||||
<version>${ratpack.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.ratpack</groupId>
|
||||
<artifactId>ratpack-test</artifactId>
|
||||
<version>${ratpack.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>${h2.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${httpclient.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpcore</artifactId>
|
||||
<version>${httpcore.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<ratpack.version>1.5.4</ratpack.version>
|
||||
<httpclient.version>4.5.3</httpclient.version>
|
||||
<httpcore.version>4.4.6</httpcore.version>
|
||||
<hystrix.version>1.5.12</hystrix.version>
|
||||
<groovy.sql.version>2.4.15</groovy.sql.version>
|
||||
<ratpack.test.latest.version>1.6.1</ratpack.test.latest.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.baeldung;
|
||||
|
||||
@Grab('io.ratpack:ratpack-groovy:1.6.1')
|
||||
import static ratpack.groovy.Groovy.ratpack
|
||||
|
||||
import com.baeldung.model.User
|
||||
import com.google.common.reflect.TypeToken
|
||||
import ratpack.exec.Promise
|
||||
import ratpack.handling.Context
|
||||
import ratpack.jackson.Jackson
|
||||
import groovy.sql.Sql
|
||||
import java.sql.Connection
|
||||
import java.sql.PreparedStatement
|
||||
import java.sql.ResultSet
|
||||
import ratpack.hikari.HikariModule
|
||||
import javax.sql.DataSource;
|
||||
|
||||
ratpack {
|
||||
serverConfig { port(5050) }
|
||||
bindings {
|
||||
module(HikariModule) { config ->
|
||||
config.dataSourceClassName = 'org.h2.jdbcx.JdbcDataSource'
|
||||
config.addDataSourceProperty('URL', "jdbc:h2:mem:devDB;INIT=RUNSCRIPT FROM 'classpath:/User.sql'")
|
||||
}
|
||||
}
|
||||
|
||||
handlers {
|
||||
|
||||
get { render 'Hello World from Ratpack with Groovy!!' }
|
||||
|
||||
get("greet/:name") { Context ctx ->
|
||||
render "Hello " + ctx.getPathTokens().get("name") + "!!!"
|
||||
}
|
||||
|
||||
get("data") {
|
||||
render Jackson.json([title: "Mr", name: "Norman", country: "USA"])
|
||||
}
|
||||
|
||||
post("user") {
|
||||
Promise<User> user = parse(Jackson.fromJson(User))
|
||||
user.then { u -> render u.name }
|
||||
}
|
||||
|
||||
get('fetchUserName/:id') { Context ctx ->
|
||||
Connection connection = ctx.get(DataSource.class).getConnection()
|
||||
PreparedStatement queryStatement = connection.prepareStatement("SELECT NAME FROM USER WHERE ID=?")
|
||||
queryStatement.setInt(1, Integer.parseInt(ctx.getPathTokens().get("id")))
|
||||
ResultSet resultSet = queryStatement.executeQuery()
|
||||
resultSet.next()
|
||||
render resultSet.getString(1)
|
||||
}
|
||||
|
||||
get('fetchUsers') {
|
||||
def db = [url:'jdbc:h2:mem:devDB']
|
||||
def sql = Sql.newInstance(db.url, db.user, db.password)
|
||||
def users = sql.rows("SELECT * FROM USER");
|
||||
render(Jackson.json(users))
|
||||
}
|
||||
|
||||
post('addUser') {
|
||||
parse(Jackson.fromJson(User))
|
||||
.then { u ->
|
||||
def db = [url:'jdbc:h2:mem:devDB']
|
||||
Sql sql = Sql.newInstance(db.url, db.user, db.password)
|
||||
sql.executeInsert("INSERT INTO USER VALUES (?,?,?,?)", [
|
||||
u.id,
|
||||
u.title,
|
||||
u.name,
|
||||
u.country
|
||||
])
|
||||
render "User $u.name inserted"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.baeldung;
|
||||
|
||||
public class RatpackGroovyApp {
|
||||
|
||||
public static void main(String[] args) {
|
||||
File file = new File("src/main/groovy/com/baeldung/Ratpack.groovy");
|
||||
def shell = new GroovyShell()
|
||||
shell.evaluate(file)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.baeldung.model
|
||||
|
||||
class User {
|
||||
|
||||
long id
|
||||
String title
|
||||
String name
|
||||
String country
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.baeldung;
|
||||
|
||||
import com.baeldung.filter.RequestValidatorFilter;
|
||||
import com.baeldung.handler.EmployeeHandler;
|
||||
import com.baeldung.handler.RedirectHandler;
|
||||
import com.baeldung.model.Employee;
|
||||
import com.baeldung.repository.EmployeeRepository;
|
||||
import com.baeldung.repository.EmployeeRepositoryImpl;
|
||||
import com.zaxxer.hikari.HikariConfig;
|
||||
import io.netty.buffer.PooledByteBufAllocator;
|
||||
import ratpack.func.Action;
|
||||
import ratpack.func.Function;
|
||||
import ratpack.guice.BindingsSpec;
|
||||
import ratpack.guice.Guice;
|
||||
import ratpack.handling.Chain;
|
||||
import ratpack.hikari.HikariModule;
|
||||
import ratpack.http.client.HttpClient;
|
||||
import ratpack.jackson.Jackson;
|
||||
import ratpack.registry.Registry;
|
||||
import ratpack.server.RatpackServer;
|
||||
import ratpack.server.RatpackServerSpec;
|
||||
import ratpack.server.ServerConfig;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
final Action<HikariConfig> hikariConfigAction = hikariConfig -> {
|
||||
hikariConfig.setDataSourceClassName("org.h2.jdbcx.JdbcDataSource");
|
||||
hikariConfig.addDataSourceProperty("URL", "jdbc:h2:mem:baeldung;INIT=RUNSCRIPT FROM 'classpath:/DDL.sql'");
|
||||
};
|
||||
|
||||
final Action<BindingsSpec> bindingsSpecAction = bindings -> bindings.module(HikariModule.class, hikariConfigAction);
|
||||
final HttpClient httpClient = HttpClient.of(httpClientSpec -> {
|
||||
httpClientSpec.poolSize(10)
|
||||
.connectTimeout(Duration.of(60, ChronoUnit.SECONDS))
|
||||
.maxContentLength(ServerConfig.DEFAULT_MAX_CONTENT_LENGTH)
|
||||
.responseMaxChunkSize(16384)
|
||||
.readTimeout(Duration.of(60, ChronoUnit.SECONDS))
|
||||
.byteBufAllocator(PooledByteBufAllocator.DEFAULT);
|
||||
});
|
||||
final Function<Registry, Registry> registryFunction = Guice.registry(bindingsSpecAction);
|
||||
|
||||
final Action<Chain> chainAction = chain -> chain.all(new RequestValidatorFilter())
|
||||
.get(ctx -> ctx.render("Welcome to baeldung ratpack!!!"))
|
||||
.get("data/employees", ctx -> ctx.render(Jackson.json(createEmpList())))
|
||||
.get(":name", ctx -> ctx.render("Hello " + ctx.getPathTokens()
|
||||
.get("name") + "!!!"))
|
||||
.post(":amount", ctx -> ctx.render(" Amount $" + ctx.getPathTokens()
|
||||
.get("amount") + " added successfully !!!"));
|
||||
|
||||
final Action<Chain> routerChainAction = routerChain -> {
|
||||
routerChain.path("redirect", new RedirectHandler())
|
||||
.prefix("employee", empChain -> {
|
||||
empChain.get(":id", new EmployeeHandler());
|
||||
});
|
||||
};
|
||||
final Action<RatpackServerSpec> ratpackServerSpecAction = serverSpec -> serverSpec.registry(registryFunction)
|
||||
.registryOf(registrySpec -> {
|
||||
registrySpec.add(EmployeeRepository.class, new EmployeeRepositoryImpl());
|
||||
registrySpec.add(HttpClient.class, httpClient);
|
||||
})
|
||||
.handlers(chain -> chain.insert(routerChainAction)
|
||||
.insert(chainAction));
|
||||
|
||||
RatpackServer.start(ratpackServerSpecAction);
|
||||
}
|
||||
|
||||
private static List<Employee> createEmpList() {
|
||||
List<Employee> employees = new ArrayList<>();
|
||||
employees.add(new Employee(1L, "Mr", "John Doe"));
|
||||
employees.add(new Employee(2L, "Mr", "White Snow"));
|
||||
return employees;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.baeldung.filter;
|
||||
|
||||
import ratpack.handling.Context;
|
||||
import ratpack.handling.Handler;
|
||||
import ratpack.http.MutableHeaders;
|
||||
|
||||
public class RequestValidatorFilter implements Handler {
|
||||
|
||||
@Override
|
||||
public void handle(Context ctx) throws Exception {
|
||||
MutableHeaders headers = ctx.getResponse().getHeaders();
|
||||
headers.set("Access-Control-Allow-Origin", "*");
|
||||
ctx.next();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.baeldung.guice;
|
||||
|
||||
import com.baeldung.guice.config.DependencyModule;
|
||||
import com.baeldung.guice.service.DataPumpService;
|
||||
import com.baeldung.guice.service.ServiceFactory;
|
||||
import com.baeldung.guice.service.impl.DataPumpServiceImpl;
|
||||
|
||||
import ratpack.guice.Guice;
|
||||
import ratpack.server.RatpackServer;
|
||||
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
RatpackServer
|
||||
.start(server -> server.registry(Guice.registry(bindings -> bindings.module(DependencyModule.class)))
|
||||
.handlers(chain -> chain.get("randomString", ctx -> {
|
||||
DataPumpService dataPumpService = ctx.get(DataPumpService.class);
|
||||
ctx.render(dataPumpService.generate());
|
||||
}).get("factory", ctx -> ctx.render(ServiceFactory.getInstance().generate()))));
|
||||
|
||||
// RatpackServer.start(server -> server
|
||||
// .registry(Guice
|
||||
// .registry(bindings -> bindings.bindInstance(DataPumpService.class, new DataPumpServiceImpl())))
|
||||
// .handlers(chain -> chain.get("randomString", ctx -> {
|
||||
// DataPumpService dataPumpService = ctx.get(DataPumpService.class);
|
||||
// ctx.render(dataPumpService.generate());
|
||||
// }).get("factory", ctx -> ctx.render(ServiceFactory.getInstance().generate()))));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.baeldung.guice.config;
|
||||
|
||||
import com.baeldung.guice.service.DataPumpService;
|
||||
import com.baeldung.guice.service.impl.DataPumpServiceImpl;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Scopes;
|
||||
|
||||
public class DependencyModule extends AbstractModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(DataPumpService.class).to(DataPumpServiceImpl.class)
|
||||
.in(Scopes.SINGLETON);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.baeldung.guice.service;
|
||||
|
||||
public interface DataPumpService {
|
||||
|
||||
String generate();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.baeldung.guice.service;
|
||||
|
||||
import com.baeldung.guice.service.impl.DataPumpServiceImpl;
|
||||
|
||||
public class ServiceFactory {
|
||||
|
||||
private static DataPumpService instance;
|
||||
|
||||
public static void setInstance(DataPumpService dataPumpService) {
|
||||
instance = dataPumpService;
|
||||
}
|
||||
|
||||
public static DataPumpService getInstance() {
|
||||
if (instance == null) {
|
||||
return new DataPumpServiceImpl();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package com.baeldung.guice.service.impl;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import com.baeldung.guice.service.DataPumpService;
|
||||
|
||||
public class DataPumpServiceImpl implements DataPumpService {
|
||||
|
||||
@Override
|
||||
public String generate() {
|
||||
return UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.baeldung.handler;
|
||||
|
||||
import com.baeldung.repository.EmployeeRepository;
|
||||
import com.baeldung.model.Employee;
|
||||
import ratpack.exec.Promise;
|
||||
import ratpack.handling.Context;
|
||||
import ratpack.handling.Handler;
|
||||
|
||||
public class EmployeeHandler implements Handler {
|
||||
@Override
|
||||
public void handle(Context ctx) throws Exception {
|
||||
EmployeeRepository repository = ctx.get(EmployeeRepository.class);
|
||||
Long id = Long.valueOf(ctx.getPathTokens()
|
||||
.get("id"));
|
||||
Promise<Employee> employeePromise = repository.findEmployeeById(id);
|
||||
employeePromise.map(employee -> employee.getName())
|
||||
.then(name -> ctx.getResponse()
|
||||
.send(name));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.baeldung.handler;
|
||||
|
||||
import ratpack.handling.Context;
|
||||
import ratpack.handling.Handler;
|
||||
|
||||
public class FooHandler implements Handler {
|
||||
@Override
|
||||
public void handle(Context ctx) throws Exception {
|
||||
ctx.getResponse()
|
||||
.send("Hello Foo!");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.baeldung.handler;
|
||||
|
||||
import ratpack.exec.Promise;
|
||||
import ratpack.handling.Context;
|
||||
import ratpack.handling.Handler;
|
||||
import ratpack.http.client.HttpClient;
|
||||
import ratpack.http.client.ReceivedResponse;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
public class RedirectHandler implements Handler {
|
||||
@Override
|
||||
public void handle(Context ctx) throws Exception {
|
||||
HttpClient client = ctx.get(HttpClient.class);
|
||||
URI uri = URI.create("http://localhost:5050/employee/1");
|
||||
Promise<ReceivedResponse> responsePromise = client.get(uri);
|
||||
responsePromise.map(response -> response.getBody()
|
||||
.getText()
|
||||
.toUpperCase())
|
||||
.then(responseText -> ctx.getResponse()
|
||||
.send(responseText));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.baeldung.hystrix;
|
||||
|
||||
import com.netflix.hystrix.HystrixCommand;
|
||||
import com.netflix.hystrix.HystrixCommandGroupKey;
|
||||
import com.netflix.hystrix.HystrixCommandProperties;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* @author aiet
|
||||
*/
|
||||
public class HystrixAsyncHttpCommand extends HystrixCommand<String> {
|
||||
|
||||
private URI uri;
|
||||
private RequestConfig requestConfig;
|
||||
|
||||
HystrixAsyncHttpCommand(URI uri, int timeoutMillis) {
|
||||
super(Setter
|
||||
.withGroupKey(HystrixCommandGroupKey.Factory.asKey("hystrix-ratpack-async"))
|
||||
.andCommandPropertiesDefaults(HystrixCommandProperties
|
||||
.Setter()
|
||||
.withExecutionTimeoutInMilliseconds(timeoutMillis)));
|
||||
requestConfig = RequestConfig
|
||||
.custom()
|
||||
.setSocketTimeout(timeoutMillis)
|
||||
.setConnectTimeout(timeoutMillis)
|
||||
.setConnectionRequestTimeout(timeoutMillis)
|
||||
.build();
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String run() throws Exception {
|
||||
return EntityUtils.toString(HttpClientBuilder
|
||||
.create()
|
||||
.setDefaultRequestConfig(requestConfig)
|
||||
.setDefaultHeaders(Collections.singleton(new BasicHeader("User-Agent", "Baeldung Blocking HttpClient")))
|
||||
.build()
|
||||
.execute(new HttpGet(uri))
|
||||
.getEntity());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getFallback() {
|
||||
return "eugenp's async fallback profile";
|
||||
}
|
||||
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package com.baeldung.hystrix;
|
||||
|
||||
import com.netflix.hystrix.HystrixCommandGroupKey;
|
||||
import com.netflix.hystrix.HystrixCommandProperties;
|
||||
import com.netflix.hystrix.HystrixObservableCommand;
|
||||
import ratpack.http.client.HttpClient;
|
||||
import ratpack.rx.RxRatpack;
|
||||
import rx.Observable;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* @author aiet
|
||||
*/
|
||||
public class HystrixReactiveHttpCommand extends HystrixObservableCommand<String> {
|
||||
|
||||
private HttpClient httpClient;
|
||||
private URI uri;
|
||||
|
||||
HystrixReactiveHttpCommand(HttpClient httpClient, URI uri, int timeoutMillis) {
|
||||
super(Setter
|
||||
.withGroupKey(HystrixCommandGroupKey.Factory.asKey("hystrix-ratpack-reactive"))
|
||||
.andCommandPropertiesDefaults(HystrixCommandProperties
|
||||
.Setter()
|
||||
.withExecutionTimeoutInMilliseconds(timeoutMillis)));
|
||||
this.httpClient = httpClient;
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Observable<String> construct() {
|
||||
return RxRatpack.observe(httpClient
|
||||
.get(uri, requestSpec -> requestSpec.headers(mutableHeaders -> mutableHeaders.add("User-Agent", "Baeldung HttpClient")))
|
||||
.map(receivedResponse -> receivedResponse
|
||||
.getBody()
|
||||
.getText()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Observable<String> resumeWithFallback() {
|
||||
return Observable.just("eugenp's reactive fallback profile");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.baeldung.hystrix;
|
||||
|
||||
import com.netflix.hystrix.HystrixCommand;
|
||||
import com.netflix.hystrix.HystrixCommandGroupKey;
|
||||
import com.netflix.hystrix.HystrixCommandProperties;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* @author aiet
|
||||
*/
|
||||
public class HystrixSyncHttpCommand extends HystrixCommand<String> {
|
||||
|
||||
private URI uri;
|
||||
private RequestConfig requestConfig;
|
||||
|
||||
HystrixSyncHttpCommand(URI uri, int timeoutMillis) {
|
||||
super(Setter
|
||||
.withGroupKey(HystrixCommandGroupKey.Factory.asKey("hystrix-ratpack-sync"))
|
||||
.andCommandPropertiesDefaults(HystrixCommandProperties
|
||||
.Setter()
|
||||
.withExecutionTimeoutInMilliseconds(timeoutMillis)));
|
||||
requestConfig = RequestConfig
|
||||
.custom()
|
||||
.setSocketTimeout(timeoutMillis)
|
||||
.setConnectTimeout(timeoutMillis)
|
||||
.setConnectionRequestTimeout(timeoutMillis)
|
||||
.build();
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String run() throws Exception {
|
||||
HttpGet request = new HttpGet(uri);
|
||||
return EntityUtils.toString(HttpClientBuilder
|
||||
.create()
|
||||
.setDefaultRequestConfig(requestConfig)
|
||||
.setDefaultHeaders(Collections.singleton(new BasicHeader("User-Agent", "Baeldung Blocking HttpClient")))
|
||||
.build()
|
||||
.execute(request)
|
||||
.getEntity());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getFallback() {
|
||||
return "eugenp's sync fallback profile";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.baeldung.hystrix;
|
||||
|
||||
import ratpack.guice.Guice;
|
||||
import ratpack.http.client.HttpClient;
|
||||
import ratpack.hystrix.HystrixMetricsEventStreamHandler;
|
||||
import ratpack.hystrix.HystrixModule;
|
||||
import ratpack.server.RatpackServer;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
public class RatpackHystrixApp {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
final int timeout = Integer.valueOf(System.getProperty("ratpack.hystrix.timeout"));
|
||||
final URI eugenGithubProfileUri = new URI("https://api.github.com/users/eugenp");
|
||||
|
||||
RatpackServer.start(server -> server
|
||||
.registry(Guice.registry(bindingsSpec -> bindingsSpec.module(new HystrixModule().sse())))
|
||||
.handlers(chain -> chain
|
||||
.get("rx", ctx -> new HystrixReactiveHttpCommand(ctx.get(HttpClient.class), eugenGithubProfileUri, timeout)
|
||||
.toObservable()
|
||||
.subscribe(ctx::render))
|
||||
.get("async", ctx -> ctx.render(new HystrixAsyncHttpCommand(eugenGithubProfileUri, timeout)
|
||||
.queue()
|
||||
.get()))
|
||||
.get("sync", ctx -> ctx.render(new HystrixSyncHttpCommand(eugenGithubProfileUri, timeout).execute()))
|
||||
.get("hystrix", new HystrixMetricsEventStreamHandler())));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.baeldung.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class Employee implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 3077867088762010705L;
|
||||
|
||||
private Long id;
|
||||
private String title;
|
||||
private String name;
|
||||
|
||||
public Employee(Long id, String title, String name) {
|
||||
super();
|
||||
this.id = id;
|
||||
this.title = title;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.baeldung.model;
|
||||
/**
|
||||
*
|
||||
*POJO class for Movie object
|
||||
*/
|
||||
public class Movie {
|
||||
|
||||
private String name;
|
||||
|
||||
private String year;
|
||||
|
||||
private String director;
|
||||
|
||||
private Double rating;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getYear() {
|
||||
return year;
|
||||
}
|
||||
|
||||
public void setYear(String year) {
|
||||
this.year = year;
|
||||
}
|
||||
|
||||
public String getDirector() {
|
||||
return director;
|
||||
}
|
||||
|
||||
public void setDirector(String director) {
|
||||
this.director = director;
|
||||
}
|
||||
|
||||
public Double getRating() {
|
||||
return rating;
|
||||
}
|
||||
|
||||
public void setRating(Double rating) {
|
||||
this.rating = rating;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
package com.baeldung.model;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
public class Quote {
|
||||
|
||||
private Instant ts;
|
||||
private String symbol;
|
||||
private double value;
|
||||
|
||||
public Quote() {}
|
||||
|
||||
|
||||
public Quote(Instant ts, String symbol, double value) {
|
||||
this.ts = ts;
|
||||
this.symbol = symbol;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the ts
|
||||
*/
|
||||
public Instant getTs() {
|
||||
return ts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ts the ts to set
|
||||
*/
|
||||
public void setTs(Instant ts) {
|
||||
this.ts = ts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the symbol
|
||||
*/
|
||||
public String getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param symbol the symbol to set
|
||||
*/
|
||||
public void setSymbol(String symbol) {
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the value
|
||||
*/
|
||||
public double getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value the value to set
|
||||
*/
|
||||
public void setValue(double value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((symbol == null) ? 0 : symbol.hashCode());
|
||||
result = prime * result + ((ts == null) ? 0 : ts.hashCode());
|
||||
long temp;
|
||||
temp = Double.doubleToLongBits(value);
|
||||
result = prime * result + (int) (temp ^ (temp >>> 32));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Quote other = (Quote) obj;
|
||||
if (symbol == null) {
|
||||
if (other.symbol != null)
|
||||
return false;
|
||||
} else if (!symbol.equals(other.symbol))
|
||||
return false;
|
||||
if (ts == null) {
|
||||
if (other.ts != null)
|
||||
return false;
|
||||
} else if (!ts.equals(other.ts))
|
||||
return false;
|
||||
if (Double.doubleToLongBits(value) != Double.doubleToLongBits(other.value))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Quote [ts=" + ts + ", symbol=" + symbol + ", value=" + value + "]";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.baeldung.repository;
|
||||
|
||||
import com.baeldung.model.Employee;
|
||||
import ratpack.exec.Promise;
|
||||
|
||||
public interface EmployeeRepository {
|
||||
|
||||
Promise<Employee> findEmployeeById(Long id) throws Exception;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.baeldung.repository;
|
||||
|
||||
import com.baeldung.model.Employee;
|
||||
import ratpack.exec.Promise;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class EmployeeRepositoryImpl implements EmployeeRepository {
|
||||
|
||||
private static final Map<Long, Employee> EMPLOYEE_MAP = new HashMap<>();
|
||||
|
||||
public EmployeeRepositoryImpl() {
|
||||
EMPLOYEE_MAP.put(1L, new Employee(1L, "Ms", "Jane Doe"));
|
||||
EMPLOYEE_MAP.put(2L, new Employee(2L, "Mr", "NY"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Promise<Employee> findEmployeeById(Long id) throws Exception {
|
||||
return Promise.async(downstream -> {
|
||||
Thread.sleep(500);
|
||||
downstream.success(EMPLOYEE_MAP.get(id));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.baeldung.rxjava;
|
||||
|
||||
import ratpack.error.ServerErrorHandler;
|
||||
import ratpack.rx.RxRatpack;
|
||||
import ratpack.server.RatpackServer;
|
||||
import rx.Observable;
|
||||
|
||||
public class RatpackErrorHandlingApp {
|
||||
|
||||
/**
|
||||
* Try hitting http://localhost:5050/error to see the error handler in action
|
||||
* @param args
|
||||
* @throws Exception
|
||||
*/
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
RxRatpack.initialize();
|
||||
RatpackServer.start(def -> def.registryOf(regSpec -> regSpec.add(ServerErrorHandler.class, (ctx, throwable) -> {
|
||||
ctx.render("Error caught by handler : " + throwable.getMessage());
|
||||
}))
|
||||
.handlers(chain -> chain.get("error", ctx -> {
|
||||
Observable.<String> error(new Exception("Error from observable"))
|
||||
.subscribe(s -> {
|
||||
});
|
||||
})));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.baeldung.rxjava;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.baeldung.model.Movie;
|
||||
import com.baeldung.rxjava.service.MoviePromiseService;
|
||||
import com.baeldung.rxjava.service.impl.MoviePromiseServiceImpl;
|
||||
|
||||
import ratpack.exec.Promise;
|
||||
import ratpack.handling.Handler;
|
||||
import ratpack.jackson.Jackson;
|
||||
import ratpack.rx.RxRatpack;
|
||||
import ratpack.server.RatpackServer;
|
||||
|
||||
public class RatpackObserveApp {
|
||||
/**
|
||||
* Try hitting http://localhost:5050/movies or http://localhost:5050/movie to see the application in action.
|
||||
*
|
||||
* @param args
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
RxRatpack.initialize();
|
||||
|
||||
Handler moviePromiseHandler = ctx -> {
|
||||
MoviePromiseService promiseSvc = ctx.get(MoviePromiseService.class);
|
||||
Promise<Movie> moviePromise = promiseSvc.getMovie();
|
||||
RxRatpack.observe(moviePromise)
|
||||
.subscribe(movie -> ctx.render(Jackson.json(movie)));
|
||||
};
|
||||
|
||||
Handler moviesPromiseHandler = ctx -> {
|
||||
MoviePromiseService promiseSvc = ctx.get(MoviePromiseService.class);
|
||||
Promise<List<Movie>> moviePromises = promiseSvc.getMovies();
|
||||
RxRatpack.observeEach(moviePromises)
|
||||
.toList()
|
||||
.subscribe(movie -> ctx.render(Jackson.json(movie)));
|
||||
};
|
||||
|
||||
RatpackServer.start(def -> def.registryOf(regSpec -> regSpec.add(MoviePromiseService.class, new MoviePromiseServiceImpl()))
|
||||
.handlers(chain -> chain.get("movie", moviePromiseHandler)
|
||||
.get("movies", moviesPromiseHandler)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.baeldung.rxjava;
|
||||
|
||||
import com.baeldung.model.Movie;
|
||||
import com.baeldung.rxjava.service.MovieObservableService;
|
||||
import com.baeldung.rxjava.service.impl.MovieObservableServiceImpl;
|
||||
|
||||
import ratpack.jackson.Jackson;
|
||||
import ratpack.rx.RxRatpack;
|
||||
import ratpack.server.RatpackServer;
|
||||
import rx.Observable;
|
||||
|
||||
public class RatpackParallelismApp {
|
||||
|
||||
/**
|
||||
* Try hitting http://localhost:5050/movies to see the application in action.
|
||||
*
|
||||
* @param args
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
RxRatpack.initialize();
|
||||
RatpackServer.start(def -> def.registryOf(regSpec -> regSpec.add(MovieObservableService.class, new MovieObservableServiceImpl()))
|
||||
.handlers(chain -> chain.get("movies", ctx -> {
|
||||
MovieObservableService movieSvc = ctx.get(MovieObservableService.class);
|
||||
Observable<Movie> movieObs = movieSvc.getMovies();
|
||||
Observable<String> upperCasedNames = movieObs.compose(RxRatpack::forkEach)
|
||||
.map(movie -> movie.getName()
|
||||
.toUpperCase())
|
||||
.serialize();
|
||||
RxRatpack.promise(upperCasedNames)
|
||||
.then(movie -> {
|
||||
ctx.render(Jackson.json(movie));
|
||||
});
|
||||
})));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.baeldung.rxjava;
|
||||
|
||||
import com.baeldung.model.Movie;
|
||||
import com.baeldung.rxjava.service.MovieObservableService;
|
||||
import com.baeldung.rxjava.service.impl.MovieObservableServiceImpl;
|
||||
|
||||
import ratpack.handling.Handler;
|
||||
import ratpack.jackson.Jackson;
|
||||
import ratpack.rx.RxRatpack;
|
||||
import ratpack.server.RatpackServer;
|
||||
import rx.Observable;
|
||||
|
||||
public class RatpackPromiseApp {
|
||||
|
||||
/**
|
||||
* Try hitting http://localhost:5050/movies or http://localhost:5050/movie to see the application in action.
|
||||
*
|
||||
* @param args
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
RxRatpack.initialize();
|
||||
|
||||
Handler movieHandler = (ctx) -> {
|
||||
MovieObservableService movieSvc = ctx.get(MovieObservableService.class);
|
||||
Observable<Movie> movieObs = movieSvc.getMovie();
|
||||
RxRatpack.promiseSingle(movieObs)
|
||||
.then(movie -> ctx.render(Jackson.json(movie)));
|
||||
};
|
||||
|
||||
Handler moviesHandler = (ctx) -> {
|
||||
MovieObservableService movieSvc = ctx.get(MovieObservableService.class);
|
||||
Observable<Movie> movieObs = movieSvc.getMovies();
|
||||
RxRatpack.promise(movieObs)
|
||||
.then(movie -> ctx.render(Jackson.json(movie)));
|
||||
};
|
||||
|
||||
RatpackServer.start(def -> def.registryOf(rSpec -> rSpec.add(MovieObservableService.class, new MovieObservableServiceImpl()))
|
||||
.handlers(chain -> chain.get("movie", movieHandler)
|
||||
.get("movies", moviesHandler)));
|
||||
}
|
||||
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.baeldung.rxjava.service;
|
||||
|
||||
import com.baeldung.model.Movie;
|
||||
|
||||
import rx.Observable;
|
||||
|
||||
public interface MovieObservableService {
|
||||
|
||||
Observable<Movie> getMovies();
|
||||
|
||||
Observable<Movie> getMovie();
|
||||
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package com.baeldung.rxjava.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.baeldung.model.Movie;
|
||||
|
||||
import ratpack.exec.Promise;
|
||||
|
||||
public interface MoviePromiseService {
|
||||
|
||||
Promise<List<Movie>> getMovies();
|
||||
|
||||
Promise<Movie> getMovie();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.baeldung.rxjava.service;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
import org.reactivestreams.Publisher;
|
||||
|
||||
import com.baeldung.model.Quote;
|
||||
|
||||
import ratpack.stream.Streams;
|
||||
|
||||
public class QuotesService {
|
||||
|
||||
private final ScheduledExecutorService executorService;
|
||||
private static Random rnd = new Random();
|
||||
private static String[] symbols = new String[] {
|
||||
"MSFT",
|
||||
"ORCL",
|
||||
"GOOG",
|
||||
"AAPL",
|
||||
"CSCO"
|
||||
};
|
||||
|
||||
public QuotesService(ScheduledExecutorService executorService) {
|
||||
this.executorService = executorService;
|
||||
}
|
||||
|
||||
public Publisher<Quote> newTicker() {
|
||||
return Streams.periodically(executorService, Duration.ofSeconds(2), (t) -> {
|
||||
|
||||
return randomQuote();
|
||||
});
|
||||
}
|
||||
|
||||
private static Quote randomQuote() {
|
||||
return new Quote (
|
||||
Instant.now(),
|
||||
symbols[rnd.nextInt(symbols.length)],
|
||||
Math.round(rnd.nextDouble()*100)
|
||||
);
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package com.baeldung.rxjava.service.impl;
|
||||
|
||||
import com.baeldung.model.Movie;
|
||||
import com.baeldung.rxjava.service.MovieObservableService;
|
||||
|
||||
import rx.Observable;
|
||||
|
||||
public class MovieObservableServiceImpl implements MovieObservableService {
|
||||
|
||||
@Override
|
||||
public Observable<Movie> getMovie() {
|
||||
Movie movie = new Movie();
|
||||
movie.setName("The Godfather");
|
||||
movie.setYear("1972");
|
||||
movie.setDirector("Coppola");
|
||||
movie.setRating(9.2);
|
||||
return Observable.just(movie);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Observable<Movie> getMovies() {
|
||||
Movie movie = new Movie();
|
||||
movie.setName("The Godfather");
|
||||
movie.setYear("1972");
|
||||
movie.setDirector("Coppola");
|
||||
movie.setRating(9.2);
|
||||
Movie movie2 = new Movie();
|
||||
movie2.setName("The Godfather Part 2");
|
||||
movie2.setYear("1974");
|
||||
movie2.setDirector("Coppola");
|
||||
movie2.setRating(9.0);
|
||||
return Observable.just(movie, movie2);
|
||||
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package com.baeldung.rxjava.service.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.baeldung.model.Movie;
|
||||
import com.baeldung.rxjava.service.MoviePromiseService;
|
||||
|
||||
import ratpack.exec.Promise;
|
||||
|
||||
public class MoviePromiseServiceImpl implements MoviePromiseService {
|
||||
|
||||
@Override
|
||||
public Promise<Movie> getMovie() {
|
||||
Movie movie = new Movie();
|
||||
movie.setName("The Godfather");
|
||||
movie.setYear("1972");
|
||||
movie.setDirector("Coppola");
|
||||
movie.setRating(9.2);
|
||||
return Promise.value(movie);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Promise<List<Movie>> getMovies() {
|
||||
Movie movie = new Movie();
|
||||
movie.setName("The Godfather");
|
||||
movie.setYear("1972");
|
||||
movie.setDirector("Coppola");
|
||||
movie.setRating(9.2);
|
||||
Movie movie2 = new Movie();
|
||||
movie2.setName("The Godfather Part 2");
|
||||
movie2.setYear("1974");
|
||||
movie2.setDirector("Coppola");
|
||||
movie2.setRating(9.0);
|
||||
List<Movie> movies = new ArrayList<>();
|
||||
movies.add(movie);
|
||||
movies.add(movie2);
|
||||
return Promise.value(movies);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.baeldung.spring;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author aiet
|
||||
*/
|
||||
public interface ArticleList {
|
||||
|
||||
List<String> articles();
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.baeldung.spring;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author aiet
|
||||
*/
|
||||
@Configuration
|
||||
public class Config {
|
||||
|
||||
@Bean
|
||||
public Content content() {
|
||||
return () -> "hello baeldung!";
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ArticleList articles() {
|
||||
return () -> Arrays.asList("Introduction to Ratpack", "Ratpack Google Guice Integration", "Ratpack Spring Boot Integration");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.baeldung.spring;
|
||||
|
||||
/**
|
||||
* @author aiet
|
||||
*/
|
||||
public interface Content {
|
||||
|
||||
String body();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.baeldung.spring;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import ratpack.func.Action;
|
||||
import ratpack.handling.Chain;
|
||||
import ratpack.server.ServerConfig;
|
||||
import ratpack.spring.config.EnableRatpack;
|
||||
|
||||
/**
|
||||
* @author aiet
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@EnableRatpack
|
||||
public class EmbedRatpackApp {
|
||||
|
||||
@Autowired private Content content;
|
||||
@Autowired private ArticleList list;
|
||||
|
||||
@Bean
|
||||
public Action<Chain> hello() {
|
||||
return chain -> chain.get("hello", ctx -> ctx.render(content.body()));
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Action<Chain> list() {
|
||||
return chain -> chain.get("list", ctx -> ctx.render(list
|
||||
.articles()
|
||||
.toString()));
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ServerConfig ratpackServerConfig() {
|
||||
return ServerConfig
|
||||
.builder()
|
||||
.findBaseDir("public")
|
||||
.build();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(EmbedRatpackApp.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
package com.baeldung.spring;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.reactivestreams.Publisher;
|
||||
import org.reactivestreams.Subscriber;
|
||||
import org.reactivestreams.Subscription;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
import com.baeldung.model.Quote;
|
||||
import com.baeldung.rxjava.service.QuotesService;
|
||||
|
||||
import groovy.util.logging.Slf4j;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import ratpack.func.Action;
|
||||
import ratpack.handling.Chain;
|
||||
import ratpack.http.ResponseChunks;
|
||||
import ratpack.http.Status;
|
||||
import ratpack.server.ServerConfig;
|
||||
import ratpack.spring.config.EnableRatpack;
|
||||
import ratpack.sse.ServerSentEvents;
|
||||
import ratpack.stream.Streams;
|
||||
import ratpack.stream.TransformablePublisher;
|
||||
import ratpack.websocket.WebSockets;
|
||||
import rx.subscriptions.Subscriptions;
|
||||
|
||||
/**
|
||||
* @author psevestre
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@EnableRatpack
|
||||
public class EmbedRatpackStreamsApp {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(EmbedRatpackStreamsApp.class);
|
||||
|
||||
@Autowired
|
||||
private QuotesService quotesService;
|
||||
|
||||
private AtomicLong idSeq = new AtomicLong(0);
|
||||
|
||||
|
||||
@Bean
|
||||
public ScheduledExecutorService executorService() {
|
||||
return Executors.newScheduledThreadPool(1);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public QuotesService quotesService(ScheduledExecutorService executor) {
|
||||
return new QuotesService(executor);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Action<Chain> quotes() {
|
||||
ServerSentEvents sse = ServerSentEvents.serverSentEvents(quotesService.newTicker(), (evt) -> {
|
||||
evt
|
||||
.id(Long.toString(idSeq.incrementAndGet()))
|
||||
.event("quote")
|
||||
.data( q -> q.toString());
|
||||
});
|
||||
|
||||
return chain -> chain.get("quotes", ctx -> ctx.render(sse));
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Action<Chain> quotesWS() {
|
||||
Publisher<String> pub = Streams.transformable(quotesService.newTicker())
|
||||
.map(Quote::toString);
|
||||
return chain -> chain.get("quotes-ws", ctx -> WebSockets.websocketBroadcast(ctx, pub));
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Action<Chain> uploadFile() {
|
||||
|
||||
return chain -> chain.post("upload", ctx -> {
|
||||
TransformablePublisher<? extends ByteBuf> pub = ctx.getRequest().getBodyStream();
|
||||
pub.subscribe(new Subscriber<ByteBuf>() {
|
||||
private Subscription sub;
|
||||
@Override
|
||||
public void onSubscribe(Subscription sub) {
|
||||
this.sub = sub;
|
||||
sub.request(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(ByteBuf t) {
|
||||
try {
|
||||
int len = t.readableBytes();
|
||||
log.info("Got {} bytes", len);
|
||||
|
||||
// Do something useful with data
|
||||
|
||||
// Request next chunk
|
||||
sub.request(1);
|
||||
}
|
||||
finally {
|
||||
// DO NOT FORGET to RELEASE !
|
||||
t.release();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable t) {
|
||||
ctx.getResponse().status(500);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
ctx.getResponse().status(202);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Action<Chain> download() {
|
||||
return chain -> chain.get("download", ctx -> {
|
||||
ctx.getResponse().sendStream(new RandomBytesPublisher(1024,512));
|
||||
});
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Action<Chain> downloadChunks() {
|
||||
return chain -> chain.get("downloadChunks", ctx -> {
|
||||
ctx.render(ResponseChunks.bufferChunks("application/octetstream",
|
||||
new RandomBytesPublisher(1024,512)));
|
||||
});
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ServerConfig ratpackServerConfig() {
|
||||
return ServerConfig
|
||||
.builder()
|
||||
.findBaseDir("public")
|
||||
.build();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(EmbedRatpackStreamsApp.class, args);
|
||||
}
|
||||
|
||||
|
||||
public static class RandomBytesPublisher implements Publisher<ByteBuf> {
|
||||
|
||||
private int bufCount;
|
||||
private int bufSize;
|
||||
private Random rnd = new Random();
|
||||
|
||||
|
||||
RandomBytesPublisher(int bufCount, int bufSize) {
|
||||
this.bufCount = bufCount;
|
||||
this.bufSize = bufSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribe(Subscriber<? super ByteBuf> s) {
|
||||
s.onSubscribe(new Subscription() {
|
||||
|
||||
private boolean cancelled = false;
|
||||
private boolean recurse;
|
||||
private long requested = 0;
|
||||
|
||||
@Override
|
||||
public void request(long n) {
|
||||
if ( bufCount == 0 ) {
|
||||
s.onComplete();
|
||||
return;
|
||||
}
|
||||
|
||||
requested += n;
|
||||
if ( recurse ) {
|
||||
return;
|
||||
}
|
||||
|
||||
recurse = true;
|
||||
try {
|
||||
while ( requested-- > 0 && !cancelled && bufCount-- > 0 ) {
|
||||
byte[] data = new byte[bufSize];
|
||||
rnd.nextBytes(data);
|
||||
ByteBuf buf = Unpooled.wrappedBuffer(data);
|
||||
s.onNext(buf);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
recurse = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
cancelled = true;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.baeldung.spring;
|
||||
|
||||
import ratpack.server.RatpackServer;
|
||||
|
||||
import static ratpack.spring.Spring.spring;
|
||||
|
||||
public class EmbedSpringBootApp {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
RatpackServer.start(server -> server
|
||||
.registry(spring(Config.class))
|
||||
.handlers(chain -> chain.get(ctx -> ctx.render(ctx
|
||||
.get(Content.class)
|
||||
.body()))));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
DROP TABLE IF EXISTS employee;
|
||||
CREATE TABLE employee (
|
||||
id bigint auto_increment primary key,
|
||||
title varchar(255),
|
||||
name varchar(255)
|
||||
)
|
||||
@@ -0,0 +1,10 @@
|
||||
DROP TABLE IF EXISTS USER;
|
||||
CREATE TABLE USER (
|
||||
ID BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
TITLE VARCHAR(255),
|
||||
NAME VARCHAR(255),
|
||||
COUNTRY VARCHAR(255)
|
||||
);
|
||||
|
||||
INSERT INTO USER VALUES(1,'Mr','Norman Potter', 'USA');
|
||||
INSERT INTO USER VALUES(2,'Miss','Ketty Smith', 'FRANCE');
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
||||
@@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Special Static Resource</title>
|
||||
</head>
|
||||
<body>
|
||||
This page is static.
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.baeldung;
|
||||
|
||||
import ratpack.groovy.Groovy
|
||||
import ratpack.groovy.test.GroovyRatpackMainApplicationUnderTest;
|
||||
import ratpack.test.http.TestHttpClient;
|
||||
import ratpack.test.ServerBackedApplicationUnderTest;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.JUnit4
|
||||
import ratpack.test.MainClassApplicationUnderTest
|
||||
|
||||
class RatpackGroovySpec {
|
||||
|
||||
ServerBackedApplicationUnderTest ratpackGroovyApp = new MainClassApplicationUnderTest(RatpackGroovyApp.class)
|
||||
@Delegate TestHttpClient client = TestHttpClient.testHttpClient(ratpackGroovyApp)
|
||||
|
||||
@Test
|
||||
void "test if app is started"() {
|
||||
when:
|
||||
get("")
|
||||
|
||||
then:
|
||||
assert response.statusCode == 200
|
||||
assert response.body.text == "Hello World from Ratpack with Groovy!!"
|
||||
}
|
||||
|
||||
@Test
|
||||
void "test greet with name"() {
|
||||
when:
|
||||
get("greet/Lewis")
|
||||
|
||||
then:
|
||||
assert response.statusCode == 200
|
||||
assert response.body.text == "Hello Lewis!!!"
|
||||
}
|
||||
|
||||
@Test
|
||||
void "test fetchUsers"() {
|
||||
when:
|
||||
get("fetchUsers")
|
||||
|
||||
then:
|
||||
assert response.statusCode == 200
|
||||
assert response.body.text == '[{"ID":1,"TITLE":"Mr","NAME":"Norman Potter","COUNTRY":"USA"},{"ID":2,"TITLE":"Miss","NAME":"Ketty Smith","COUNTRY":"FRANCE"}]'
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.baeldung;
|
||||
|
||||
import com.baeldung.model.Employee;
|
||||
import org.junit.Test;
|
||||
import ratpack.exec.Promise;
|
||||
import ratpack.func.Action;
|
||||
import ratpack.handling.Chain;
|
||||
import ratpack.handling.Handler;
|
||||
import ratpack.registry.Registry;
|
||||
import ratpack.test.embed.EmbeddedApp;
|
||||
import ratpack.test.exec.ExecHarness;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class AppHttpUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenAnyUri_GetEmployeeFromSameRegistry() throws Exception {
|
||||
Handler allHandler = ctx -> {
|
||||
Long id = Long.valueOf(ctx.getPathTokens()
|
||||
.get("id"));
|
||||
Employee employee = new Employee(id, "Mr", "NY");
|
||||
ctx.next(Registry.single(Employee.class, employee));
|
||||
};
|
||||
Handler empNameHandler = ctx -> {
|
||||
Employee employee = ctx.get(Employee.class);
|
||||
ctx.getResponse()
|
||||
.send("Name of employee with ID " + employee.getId() + " is " + employee.getName());
|
||||
};
|
||||
Handler empTitleHandler = ctx -> {
|
||||
Employee employee = ctx.get(Employee.class);
|
||||
ctx.getResponse()
|
||||
.send("Title of employee with ID " + employee.getId() + " is " + employee.getTitle());
|
||||
};
|
||||
|
||||
Action<Chain> chainAction = chain -> chain.prefix("employee/:id", empChain -> {
|
||||
empChain.all(allHandler)
|
||||
.get("name", empNameHandler)
|
||||
.get("title", empTitleHandler);
|
||||
});
|
||||
EmbeddedApp.fromHandlers(chainAction)
|
||||
.test(testHttpClient -> {
|
||||
assertEquals("Name of employee with ID 1 is NY", testHttpClient.get("employee/1/name")
|
||||
.getBody()
|
||||
.getText());
|
||||
assertEquals("Title of employee with ID 1 is Mr", testHttpClient.get("employee/1/title")
|
||||
.getBody()
|
||||
.getText());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSyncDataSource_GetDataFromPromise() throws Exception {
|
||||
String value = ExecHarness.yieldSingle(execution -> Promise.sync(() -> "Foo"))
|
||||
.getValueOrThrow();
|
||||
assertEquals("Foo", value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.baeldung;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
import com.baeldung.model.Employee;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import ratpack.test.MainClassApplicationUnderTest;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(JUnit4.class)
|
||||
public class ApplicationIntegrationTest {
|
||||
|
||||
MainClassApplicationUnderTest appUnderTest = new MainClassApplicationUnderTest(Application.class);
|
||||
|
||||
@Test
|
||||
public void givenDefaultUrl_getStaticText() {
|
||||
assertEquals("Welcome to baeldung ratpack!!!", appUnderTest.getHttpClient().getText("/"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDynamicUrl_getDynamicText() {
|
||||
assertEquals("Hello dummybot!!!", appUnderTest.getHttpClient().getText("/dummybot"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUrl_getListOfEmployee() throws JsonProcessingException {
|
||||
List<Employee> employees = new ArrayList<Employee>();
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
employees.add(new Employee(1L, "Mr", "John Doe"));
|
||||
employees.add(new Employee(2L, "Mr", "White Snow"));
|
||||
|
||||
assertEquals(mapper.writeValueAsString(employees), appUnderTest.getHttpClient().getText("/data/employees"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStaticUrl_getDynamicText() {
|
||||
assertEquals(21, appUnderTest.getHttpClient().getText("/randomString").length());
|
||||
}
|
||||
|
||||
@After
|
||||
public void shutdown() {
|
||||
appUnderTest.close();
|
||||
}
|
||||
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
package com.baeldung.hystrix;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import ratpack.test.MainClassApplicationUnderTest;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
* @author aiet
|
||||
*/
|
||||
public class RatpackHystrixAppFallbackLiveTest {
|
||||
|
||||
static MainClassApplicationUnderTest appUnderTest;
|
||||
|
||||
@BeforeClass
|
||||
public static void setup() {
|
||||
System.setProperty("ratpack.hystrix.timeout", "10");
|
||||
appUnderTest = new MainClassApplicationUnderTest(RatpackHystrixApp.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFetchReactive_thenGotFallbackProfile() {
|
||||
assertThat(appUnderTest
|
||||
.getHttpClient()
|
||||
.getText("rx"), containsString("reactive fallback profile"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFetchAsync_thenGotFallbackProfile() {
|
||||
assertThat(appUnderTest
|
||||
.getHttpClient()
|
||||
.getText("async"), containsString("async fallback profile"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFetchSync_thenGotFallbackProfile() {
|
||||
assertThat(appUnderTest
|
||||
.getHttpClient()
|
||||
.getText("sync"), containsString("sync fallback profile"));
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void clean() {
|
||||
appUnderTest.close();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.baeldung.hystrix;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import ratpack.test.MainClassApplicationUnderTest;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
* @author aiet
|
||||
*/
|
||||
public class RatpackHystrixAppLiveTest {
|
||||
|
||||
static MainClassApplicationUnderTest appUnderTest;
|
||||
|
||||
@BeforeClass
|
||||
public static void setup() {
|
||||
System.setProperty("ratpack.hystrix.timeout", "5000");
|
||||
appUnderTest = new MainClassApplicationUnderTest(RatpackHystrixApp.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFetchReactive_thenGotEugenProfile() {
|
||||
assertThat(appUnderTest
|
||||
.getHttpClient()
|
||||
.getText("rx"), containsString("www.baeldung.com"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFetchAsync_thenGotEugenProfile() {
|
||||
assertThat(appUnderTest
|
||||
.getHttpClient()
|
||||
.getText("async"), containsString("www.baeldung.com"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFetchSync_thenGotEugenProfile() {
|
||||
assertThat(appUnderTest
|
||||
.getHttpClient()
|
||||
.getText("sync"), containsString("www.baeldung.com"));
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void clean() {
|
||||
appUnderTest.close();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.baeldung.ratpack;
|
||||
|
||||
import org.reactivestreams.Publisher;
|
||||
import org.reactivestreams.Subscriber;
|
||||
import org.reactivestreams.Subscription;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
// Non-thread safe !!!
|
||||
class CompliantPublisher implements Publisher<Integer> {
|
||||
String name;
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(CompliantPublisher.class);
|
||||
private long available;
|
||||
|
||||
|
||||
public CompliantPublisher(long available) {
|
||||
this.available = available;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribe(Subscriber<? super Integer> subscriber) {
|
||||
log.info("subscribe");
|
||||
subscriber.onSubscribe(new CompliantSubscription(subscriber));
|
||||
|
||||
}
|
||||
|
||||
|
||||
private class CompliantSubscription implements Subscription {
|
||||
|
||||
private Subscriber<? super Integer> subscriber;
|
||||
private int recurseLevel;
|
||||
private long requested;
|
||||
private boolean cancelled;
|
||||
|
||||
public CompliantSubscription(Subscriber<? super Integer> subscriber) {
|
||||
this.subscriber = subscriber;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void request(long n) {
|
||||
log.info("request: requested={}, available={}", n, available);
|
||||
requested += n;
|
||||
if ( recurseLevel > 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
recurseLevel++;
|
||||
for (int i = 0 ; i < (requested) && !cancelled && available > 0 ; i++, available-- ) {
|
||||
subscriber.onNext(i);
|
||||
}
|
||||
subscriber.onComplete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
cancelled = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.baeldung.ratpack;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.reactivestreams.Subscriber;
|
||||
import org.reactivestreams.Subscription;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
public class LoggingSubscriber<T> implements Subscriber<T> {
|
||||
private static final Logger log = LoggerFactory.getLogger(LoggingSubscriber.class);
|
||||
|
||||
private Subscription subscription;
|
||||
private long requested;
|
||||
private long received;
|
||||
private CountDownLatch finished = new CountDownLatch(1);
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
log.info("onComplete: sub={}", subscription.hashCode());
|
||||
finished.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable t) {
|
||||
log.error("Error: sub={}, message={}", subscription.hashCode(), t.getMessage(),t);
|
||||
finished.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(T value) {
|
||||
log.info("onNext: sub={}, value={}", subscription.hashCode(), value);
|
||||
this.received++;
|
||||
this.requested++;
|
||||
subscription.request(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSubscribe(Subscription sub) {
|
||||
log.info("onSubscribe: sub={}", sub.hashCode());
|
||||
this.subscription = sub;
|
||||
this.received = 0;
|
||||
this.requested = 1;
|
||||
sub.request(1);
|
||||
}
|
||||
|
||||
|
||||
public long getRequested() {
|
||||
return requested;
|
||||
}
|
||||
|
||||
public long getReceived() {
|
||||
return received;
|
||||
}
|
||||
|
||||
public void block() {
|
||||
try {
|
||||
finished.await(10, TimeUnit.SECONDS);
|
||||
}
|
||||
catch(InterruptedException iex) {
|
||||
throw new RuntimeException(iex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.baeldung.ratpack;
|
||||
|
||||
import org.reactivestreams.Publisher;
|
||||
import org.reactivestreams.Subscriber;
|
||||
import org.reactivestreams.Subscription;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
public class NonCompliantPublisher implements Publisher<Integer> {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(NonCompliantPublisher.class);
|
||||
|
||||
@Override
|
||||
public void subscribe(Subscriber<? super Integer> subscriber) {
|
||||
log.info("subscribe");
|
||||
subscriber.onSubscribe(new NonCompliantSubscription(subscriber));
|
||||
}
|
||||
|
||||
private class NonCompliantSubscription implements Subscription {
|
||||
private Subscriber<? super Integer> subscriber;
|
||||
private int recurseLevel = 0;
|
||||
|
||||
public NonCompliantSubscription(Subscriber<? super Integer> subscriber) {
|
||||
this.subscriber = subscriber;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void request(long n) {
|
||||
log.info("request: n={}", n);
|
||||
if ( recurseLevel > 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
recurseLevel++;
|
||||
for (int i = 0 ; i < (n + 5) ; i ++ ) {
|
||||
subscriber.onNext(i);
|
||||
}
|
||||
subscriber.onComplete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
package com.baeldung.ratpack;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.reactivestreams.Publisher;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ratpack.exec.ExecResult;
|
||||
import ratpack.func.Action;
|
||||
import ratpack.stream.StreamEvent;
|
||||
import ratpack.stream.Streams;
|
||||
import ratpack.stream.TransformablePublisher;
|
||||
import ratpack.test.exec.ExecHarness;
|
||||
|
||||
public class RatpackStreamsUnitTest {
|
||||
|
||||
private static Logger log = LoggerFactory.getLogger(RatpackStreamsUnitTest.class);
|
||||
|
||||
@Test
|
||||
public void whenPublish_thenSuccess() {
|
||||
|
||||
Publisher<String> pub = Streams.publish(Arrays.asList("hello", "hello again"));
|
||||
LoggingSubscriber<String> sub = new LoggingSubscriber<String>();
|
||||
pub.subscribe(sub);
|
||||
sub.block();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void whenYield_thenSuccess() {
|
||||
|
||||
Publisher<String> pub = Streams.yield((t) -> {
|
||||
return t.getRequestNum() < 5 ? "hello" : null;
|
||||
});
|
||||
|
||||
LoggingSubscriber<String> sub = new LoggingSubscriber<String>();
|
||||
pub.subscribe(sub);
|
||||
sub.block();
|
||||
assertEquals(5, sub.getReceived());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenPeriodic_thenSuccess() {
|
||||
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
|
||||
Publisher<String> pub = Streams.periodically(executor, Duration.ofSeconds(1), (t) -> {
|
||||
return t < 5 ? String.format("hello %d",t): null;
|
||||
});
|
||||
|
||||
LoggingSubscriber<String> sub = new LoggingSubscriber<String>();
|
||||
pub.subscribe(sub);
|
||||
sub.block();
|
||||
assertEquals(5, sub.getReceived());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenMap_thenSuccess() throws Exception {
|
||||
|
||||
TransformablePublisher<String> pub = Streams.yield( t -> {
|
||||
return t.getRequestNum() < 5 ? t.getRequestNum() : null;
|
||||
})
|
||||
.map(v -> String.format("item %d", v));
|
||||
|
||||
ExecResult<List<String>> result = ExecHarness.yieldSingle((c) -> pub.toList() );
|
||||
assertTrue("should succeed", result.isSuccess());
|
||||
assertEquals("should have 5 items",5,result.getValue().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenNonCompliantPublisherWithBuffer_thenSuccess() throws Exception {
|
||||
|
||||
TransformablePublisher<Integer> pub = Streams.transformable(new NonCompliantPublisher())
|
||||
.wiretap(new LoggingAction("before buffer"))
|
||||
.buffer()
|
||||
.wiretap(new LoggingAction("after buffer"))
|
||||
.take(1);
|
||||
|
||||
LoggingSubscriber<Integer> sub = new LoggingSubscriber<>();
|
||||
pub.subscribe(sub);
|
||||
sub.block();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenNonCompliantPublisherWithoutBuffer_thenSuccess() throws Exception {
|
||||
TransformablePublisher<Integer> pub = Streams.transformable(new NonCompliantPublisher())
|
||||
.wiretap(new LoggingAction(""))
|
||||
.take(1);
|
||||
|
||||
LoggingSubscriber<Integer> sub = new LoggingSubscriber<>();
|
||||
pub.subscribe(sub);
|
||||
sub.block();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCompliantPublisherWithoutBatch_thenSuccess() throws Exception {
|
||||
|
||||
TransformablePublisher<Integer> pub = Streams.transformable(new CompliantPublisher(10))
|
||||
.wiretap(new LoggingAction(""));
|
||||
|
||||
LoggingSubscriber<Integer> sub = new LoggingSubscriber<>();
|
||||
pub.subscribe(sub);
|
||||
sub.block();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCompliantPublisherWithBatch_thenSuccess() throws Exception {
|
||||
|
||||
TransformablePublisher<Integer> pub = Streams.transformable(new CompliantPublisher(10))
|
||||
.wiretap(new LoggingAction("before batch"))
|
||||
.batch(5, Action.noop())
|
||||
.wiretap(new LoggingAction("after batch"));
|
||||
|
||||
LoggingSubscriber<Integer> sub = new LoggingSubscriber<>();
|
||||
pub.subscribe(sub);
|
||||
sub.block();
|
||||
}
|
||||
|
||||
private static class LoggingAction implements Action<StreamEvent<Integer>>{
|
||||
private final String label;
|
||||
|
||||
public LoggingAction(String label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(StreamEvent<Integer> e) throws Exception {
|
||||
log.info("{}: event={}", label,e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package com.baeldung.spring;
|
||||
|
||||
import org.junit.Test;
|
||||
import ratpack.test.MainClassApplicationUnderTest;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
* @author aiet
|
||||
*/
|
||||
public class EmbedRatpackAppIntegrationTest {
|
||||
|
||||
MainClassApplicationUnderTest appUnderTest = new MainClassApplicationUnderTest(EmbedRatpackApp.class);
|
||||
|
||||
@Test
|
||||
public void whenSayHello_thenGotWelcomeMessage() {
|
||||
assertEquals("hello baeldung!", appUnderTest
|
||||
.getHttpClient()
|
||||
.getText("/hello"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenRequestList_thenGotArticles() throws IOException {
|
||||
assertEquals(3, appUnderTest
|
||||
.getHttpClient()
|
||||
.getText("/list")
|
||||
.split(",").length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenRequestStaticResource_thenGotStaticContent() {
|
||||
assertThat(appUnderTest
|
||||
.getHttpClient()
|
||||
.getText("/"), containsString("page is static"));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user