SlideShare una empresa de Scribd logo
1 de 73
Descargar para leer sin conexión
Reactive microservices
with Micronaut
Álvaro Sánchez-Mariscal
@alvaro_sanchez
About me
— Coming from Madrid
!
— Developer since 2001 (Java / Spring stack).
— Grails fanboy since v0.4.
— Working @ OCI since 2015: Groovy, Grails & Micronaut!
— Father since 2017!
"
@alvaro_sanchez
DISCLAIMER
!
Work in progress
Introducing
 Introducing Micronaut
The productivity of Grails with the performance of
a compile-time, non-blocking framework.
— Designed from the ground up with microservices and the
cloud in mind.
— Ultra-lightweight and Reactive (based on Netty)
— Integrated AOP and Compile-Time DI for Java, Groovy and
Kotlin.
— HTTP Client & Server.
@alvaro_sanchez
Reactive microservices
— Any Reactive Streams implementation:
— RxJava 2.x.
— Reactor 3.x.
— Akka.
— Plain old java.util.concurrent.CompletableFuture.
@alvaro_sanchez
Micronaut is small and fast!
— JAR files: 8Mb (Java) / 12Mb (Groovy).
— Spring+Groovy: 36MB / Grails: 27Mb.
— Heap size: 7Mb (Java) / 19Mb (Groovy).
— Spring+Groovy: 33Mb / Grails: 49Mb.
— Startup time: ~1 second.
— Spring / Grails: ~3-4 seconds.
@alvaro_sanchez
No kidding!
@alvaro_sanchez
Features
Inversion of Control
Dependency Injection
Inversion of Control /
Dependency Injection
— Inspired from Spring.
— Compile-time: no reflection, no runtime proxies.
— JSR-330 (javax.inject) or Spring-like annotations.
— Implemented via annotation processors (Java and
Kotlin) and AST transformations (Groovy) that use ASM
to generate bytecode.
@alvaro_sanchez
interface Engine {
String start()
}
@Singleton
class V8Engine implements Engine {
String start() {
"Starting V8"
}
}
@Singleton
class Vehicle {
final Engine engine
@Inject Vehicle(Engine engine) {
this.engine = engine
}
String start() {
engine.start() // "Starting V8"
}
}
@alvaro_sanchez
Injectable types
— An Optional of a bean. If the bean doesn’t exist
empty() is injected. Alternatively, use @Nullable.
— An Iterable or subtype of Iterable (eg List, Collection
etc).
— A lazy Stream of beans.
— A native array of beans of a given type (Engine[]).
— A javax.inject.Provider if a circular dependency
requires it.
@alvaro_sanchez
Bean qualifiers
@Singleton
class V6Engine implements Engine { ... }
@Singleton
class V8Engine implements Engine { ... }
//Vehicle constructor
@Inject Vehicle(@Named('v8') Engine engine) {
this.engine = engine
}
@alvaro_sanchez
Bean qualifiers
@Qualifier
@Retention(RUNTIME)
@interface V8 {
}
//Vehicle constructor
@Inject Vehicle(@V8 Engine engine) {
this.engine = engine
}
@alvaro_sanchez
Refreshable beans
@Refreshable
class WeatherService {
String forecast
@PostConstruct
void init() {
forecast = "Scattered Clouds ${new Date().format('dd/MMM/yy HH:ss.SSS')}"
}
String latestForecast() {
return forecast
}
}
@alvaro_sanchez
Refreshable beans
@Controller('/weather')
class WeatherController {
@Inject
WeatherService weatherService
...
}
— Refreshable via:
— The /refresh endpoint.
— applicationContext.publishEvent(new RefreshEvent())
@alvaro_sanchez
Refreshing upon config
changes
@Bean(preDestroy = "close")
@Refreshable('mongodb')
MongoClient mongoClient(ReactiveMongoConfiguration rmc) {
return MongoClients.create(rmc.buildSettings())
}
@alvaro_sanchez
 Bean factories
@Singleton
class CrankShaft {}
@Factory
class EngineFactory {
@Bean
@Singleton
Engine v8Engine(CrankShaft crankShaft) {
new V8Engine(crankShaft)
}
}
@alvaro_sanchez
 Conditional beans
@Singleton
@Requires(beans = DataSource)
@Requires(property = "datasource.url")
class JdbcBookService implements BookService {
DataSource dataSource
public JdbcBookService(DataSource dataSource) {
this.dataSource = dataSource
}
}
@alvaro_sanchez
 Conditional beans
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PACKAGE, ElementType.TYPE})
@Requires(beans = DataSource)
@Requires(property = "datasource.url")
@interface RequiresJdbc {
}
@RequiresJdbc
class JdbcBookService implements BookService {
...
}
@alvaro_sanchez
 Supported conditions
— @Requires(classes=javax.servlet.Servlet)
— @Requires(beans=javax.sql.DataSource)
— @Requires(env='TRAVIS')
— @Requires(configuration='foo.bar')
— @Requires(sdk=Sdk.JAVA, value="1.8")
— @Requires(property='consul.enabled', value="true",
defaultValue="false")
@alvaro_sanchez
 Bean configurations
— Grouping of multiple bean definitions within a
package:
//file: src/main/groovy/com/example/json/package-info.groovy
@Configuration
@Requires(classes = com.fasterxml.jackson.databind.ObjectMapper)
package com.example.json
— All the beans from the package can be required with
@Requires(configuration='com.example.json')
@alvaro_sanchez
Life-cycle methods and events
— javax.annotation.PostConstruct is supported.
— For events:
@Singleton
class EngineInitializer implements BeanInitializedEventListener<EngineFactory> {
@Override
EngineFactory onInitialized(BeanInitializingEvent<EngineFactory> event) {
EngineFactory engineFactory = event.bean
engineFactory.rodLength = 6.6
return event.bean
}
}
@alvaro_sanchez
Application configuration
PropertySources
— Command line arguments.
— Properties from SPRING_APPLICATION_JSON (for Spring compatibility).
— Properties from MICRONAUT_APPLICATION_JSON.
— Java System Properties.
— OS environment variables.
— Enviroment-specific properties from application-{environment}.
{extension}.
— (Either .properties, .json, .yml or .groovy formats supported)
— Application-specific properties from application.{extension}.
@alvaro_sanchez
 Injecting configuration values
@Singleton
class EngineImpl implements Engine {
@Value('${my.engine.cylinders:6}')
int cylinders
}
@alvaro_sanchez
 @EachProperty
@EachProperty("myapp.datasources")
public class DataSourceConfiguration {
final String name
final URI url
}
//src/main/resources/application.properties
myapp.datasources.one = "jdbc:mysql://localhost/one"
myapp.datasources.two = "jdbc:mysql://localhost/two"
@alvaro_sanchez
 @EachBean
@Factory
class DataSourceFactory {
@EachBean(DataSourceConfiguration)
DataSource dataSource(DataSourceConfiguration cfg) {
URI url = cfg.url
return new DataSource(url)
}
}
@alvaro_sanchez
 Type-safe @ConfigurationProperties
@ConfigurationProperties('my.engine')
class EngineConfig {
@NotBlank
String manufacturer = "Ford"
@Min(1L)
int cylinders
CrankShaft crankShaft = new CrankShaft()
@ConfigurationProperties('crank-shaft')
static class CrankShaft {
Optional<Double> rodLength = Optional.empty()
}
}
@alvaro_sanchez
 Type-safe @ConfigurationProperties
#src/main/resources/application.yml
my:
engine:
manufacturer: Subaru
cylinders: 4
crank-shaft:
rodLength: 4
@alvaro_sanchez
 Type-safe @ConfigurationProperties
— Simple injection:
@Singleton
class EngineImpl implements Engine {
final EngineConfig config
EngineImpl(EngineConfig config) { //Implicit injection
this.config = config
}
}
@alvaro_sanchez
AOP
Micronaut's AOP
— Around Advice - decorates a method or class.
— Trace logging.
— Hystrix support.
— Cache abstraction.
— Circuit breaker pattern with retry support.
— Validation.
— Introduction Advice - introduces new behaviour to a class.
— HTTP client.
@alvaro_sanchez
Cache abstraction
@Singleton
@CacheConfig("pets")
class PetService {
@Cacheable
Pet findById(Long id) { ... }
@CachePut
void save(Pet pet) { ... }
@CacheInvalidate
void delete(Pet pet) { ... }
}
@alvaro_sanchez
HTTP Server
Hello World
//src/main/java/example/Application.java
public class Application {
public static void main(String[] args) {
Micronaut.run(Application.class);
}
}
@alvaro_sanchez
Hello World
//src/main/java/example/HelloController.java
@Controller("/")
public class HelloController {
@Get("/hello/{name}")
public Single<String> hello(@NotBlank String name) {
return Single.just("Hello " + name + "!");
}
}
@alvaro_sanchez
Testing with Spock
class HelloControllerSpec extends Specification {
@Shared @AutoCleanup EmbeddedServer embeddedServer =
ApplicationContext.run(EmbeddedServer)
@Shared @AutoCleanup HttpClient client =
HttpClient.create(embeddedServer.URL)
void "test hello world response"() {
expect:
client.toBlocking()
.retrieve(HttpRequest.GET('/hello/Greach')) == "Hello Greach!"
}
}
@alvaro_sanchez
Testing with JUnit
public class HelloWorldTest {
private static EmbeddedServer server;
private static HttpClient client;
@BeforeClass
public static void setupServer() {
server = ApplicationContext.run(EmbeddedServer.class);
client = server.getApplicationContext().createBean(HttpClient.class, server.getURL());
}
@AfterClass
public static void stopServer() {
if(server != null) { server.stop(); }
if(client != null) { client.stop(); }
}
@Test
public void testHelloWorkd() throws Exception {
String body = client.toBlocking().retrieve("/hello/Greach");
assertEquals(body, "Hello Greach!");
}
}
@alvaro_sanchez
Declarative routing
//Both are equivalent
@Get("/hello")
String hello() {
return "Hello World"
}
@Get
String hello() {
return "Hello World"
}
@alvaro_sanchez
Programmatic routing
@Singleton
public class MyRoutes extends DefaultRouteBuilder {
public MyRoutes(ApplicationContext beanContext) { super(beanContext); }
@Inject
void someRoutes(BookController controller, AuthorController authorController) {
GET("/conditional{/message}", controller, "hello", String.class)
.where((request)->
request.getContentType()
.map(type->type.equals(MediaType.APPLICATION_JSON_TYPE))
.orElse(false)
);
GET("/message{/message}", controller, "hello", String.class).consumes(MediaType.APPLICATION_JSON_TYPE);
GET("/books{/id}", controller, "show").nest(() ->
GET("/authors", controller)
);
}
}
@alvaro_sanchez
Request binding
— Body: String hello(@Body String body)
— Cookies: String hello(@CookieValue String myCookie)
— Headers: String hello(@Header String contentType)
— Parameters: String hello(@Parameter String myParam)
— Special cases:
— String hello(@Header Optional<String> contentType)
— String hello(@Parameter ZonedDateTime date)
@alvaro_sanchez
Direct request/response
manipulation
@Get("/hello")
HttpResponse<String> hello(HttpRequest<?> request) {
String name = request.getParameters()
.getFirst("name")
.orElse("Nobody");
return HttpResponse.ok("Hello " + name + "!!")
.header("X-My-Header", "Foo");
}
@alvaro_sanchez
Reactive request processing
@Post(consumes = MediaType.TEXT_PLAIN)
Single<MutableHttpResponse<String>> echoFlow(@Body Flowable<String> text) {
return text.collect(StringBuffer::new, StringBuffer::append)
.map(buffer ->
HttpResponse.ok(buffer.toString())
);
}
@alvaro_sanchez
Reactive responses
— Any type that implements the
org.reactivestreams.Publisher:
Flowable<String> hello() {}
— A Java's CompletableFuture instance:
CompletableFuture<String> hello() {}
— An io.micronaut.http.HttpResponse and optional
response body:
HttpResponse<Flowable<String>> hello() {}
@alvaro_sanchez
Non-reactive responses
— Any implementation of CharSequence:
String hello()
— Any simple POJO type
Book show()
@alvaro_sanchez
Threading model
The response type determines the thread pool used to
execute the request:
— Non-blocking requests will be executed in the Netty
event loop thread pool.
— Blocking requests will be executed on the I/O thread
pool.
@alvaro_sanchez
Reactive JSON parsing with
Jackson
@Post
public Single<HttpResponse<Person>> save(@Body Single<Person> person) {
return person.map(p -> {
//do something blocking, and then:
return HttpResponse.created(p);
}
);
}
@alvaro_sanchez
Non-reactive JSON parsing
If your method does not do any blocking I/O:
@Post
public HttpResponse<Person> save(@Body Person person) {
//do something, and then:
return HttpResponse.created(person);
}
@alvaro_sanchez
HTTP Client
 Basics
//src/main/groovy/example/HelloController.groovy
@Controller("/")
class HelloController {
@Get("/hello/{name}") String hello(String name) { return "Hello $name!" }
}
//src/test/groovy/example/HelloClient.groovy
@Client('/')
interface HelloClient {
@Get("/hello/{name}") String hello(String name)
}
@alvaro_sanchez
 Testing it
class HelloControllerSpec extends Specification {
@Shared @AutoCleanup EmbeddedServer embeddedServer =
ApplicationContext.run(EmbeddedServer)
void "test hello world"() {
given:
HelloClient client = embeddedServer.applicationContext.getBean(HelloClient)
expect:
client.hello("Fred") == "Hello Fred!"
}
}
@alvaro_sanchez
 Features
— Service discovery aware: Consul and Eureka support.
— Load balancing: round robin, Netflix's Ribbon.
— Reactive: based on the return types.
— Fault tolerant: retry, fallback, circuit breaker.
@alvaro_sanchez
Fallback support
@Validated
interface PetOperations<T extends Pet> {
@Get("/") Single<List<T>> list()
}
@Client(id = "pets", path = "/v1/pets")
interface PetClient extends PetOperations<Pet> {
@Get("/") Single<List<Pet>> findAll()
}
@Fallback
class PetClientFallback implements PetOperations<Pet> {
Single<List<Pet>> list() { Single.just([] as List<Pet>) }
}
@alvaro_sanchez
Retry / circuit breaker support
@Client("/dodgy-api")
@Retryable(attempts = '5', delay = '5ms')
interface ApiClient { ... }
@Singleton
@CircuitBreaker(attempts = '5', delay = '5ms', reset = '300ms')
class MyService { ... }
@alvaro_sanchez
Retryable beans
@Singleton
class Neo4jDriverBuilder {
@Retryable(ServiceUnavailableException)
Driver buildDriver() {
//build driver
}
}
@alvaro_sanchez
Serverless
Simple functions as Groovy scripts
@Field @Inject Twitter twitterClient
@CompileStatic
UpdateResult updateStatus(Message status) {
Status s = twitterClient.updateStatus(status.text)
URL url= new URL("https://twitter.com/$s.user.screenName/status/${s.id}")
return new UpdateResult(url, s.createdAt.time)
}
@alvaro_sanchez
Or with function beans
import java.util.function.Function
@FunctionBean('book')
class BookFunction implements Function<Book, Book> {
@Override
Book apply(Book book) {
book.title = book.title.toUpperCase()
return book
}
}
@alvaro_sanchez
Function clients
@FunctionClient
interface TweetClient {
Single<Result> updateStatus(String text)
static class Result {
URL url
}
}
@alvaro_sanchez
Testing: directly
void "run function directly"() {
expect:
new HelloWorldFunction()
.hello(new Person(name: "Fred"))
.text == "Hello Fred!"
}
@alvaro_sanchez
Testing: REST
void "run function as REST service"() {
given:
EmbeddedServer server = ApplicationContext.run(EmbeddedServer)
HelloClient client = server.getApplicationContext().getBean(HelloClient)
when:
Message message = client.hello("Fred").blockingGet()
then:
message.text == "Hello Fred!"
}
@alvaro_sanchez
 Testing: AWS Lambda
void "run execute function as lambda"() {
given:
ApplicationContext applicationContext = ApplicationContext.run(
'aws.lambda.functions.hello.functionName':'hello-world',
'aws.lambda.region':'us-east-1'
)
HelloClient client = applicationContext.getBean(HelloClient)
when:
Message message = client.hello("Fred").blockingGet()
then:
message.text == "Hello Fred!"
}
@alvaro_sanchez
Other goodies
Error handling with @Error
@Controller
class TestController {
@Get
HttpResponse bad() { HttpResponse.badRequest() }
@Error(status = HttpStatus.BAD_REQUEST)
HttpResponse badHandler() {
HttpResponse.status(HttpStatus.BAD_REQUEST,
"You sent me bad stuff")
}
}
@alvaro_sanchez
Error handling with @Error
— Handling exceptions:
— @Error(JsonParseException)
— Global error handling:
— @Error
@alvaro_sanchez
Request / response filters
@Filter("/hello/**")
public class TraceFilter implements HttpServerFilter {
@Override
public Publisher<MutableHttpResponse<?>> doFilter(HttpRequest<?> request,
ServerFilterChain chain) {
return traceService.trace(request)
.switchMap(aBoolean -> chain.proceed(request))
.doOnNext(res ->
res.getHeaders().add("X-Trace-Enabled", "true")
);
}
}
@alvaro_sanchez
Security solution
import io.micronaut.http.annotation.*;
import io.micronaut.security.Secured;
import java.security.Principal;
@Secured("isAuthenticated()")
@Controller("/")
public class HomeController {
@Get("/")
String index(Principal principal) {
return "Welcome, " + principal.getName();
}
}
@alvaro_sanchez
CLI
[~]$ sdk install micronaut
...
[~]$ mn create-service teams-api -build=maven 
-features=discovery-consul,security-jwt
| Service created at /tmp/teams-api
[teams-api]$ mn create-controller player
| Rendered template Controller.java to destination
src/main/java/teams/api/PlayerController.java
| Rendered template ControllerTest.java to destination
src/test/java/teams/api/PlayerControllerTest.java
@alvaro_sanchez
And much more!
— HTTP Server: SSL, CORS, Server-Sent Events.
— Production endpoints: /beans, /info, /health, /
refresh, /routes, /stop
— Service Discovery: Consul, Eureka, Kubernetes, AWS
Route 53, Ribbon.
— Distributed tracing: Zipkin, Jaeger.
— Data access: SQL, Hibernate, MongoDB, Neo4j, Redis,
Cassandra, Kafka, RabbitMQ.
@alvaro_sanchez
A!ending to the workshop?
http://bit.ly/mn-workshop
@alvaro_sanchez
Q & A
Álvaro Sánchez-Mariscal
@alvaro_sanchez

Más contenido relacionado

La actualidad más candente

Integration made easy with Apache Camel
Integration made easy with Apache CamelIntegration made easy with Apache Camel
Integration made easy with Apache CamelRosen Spasov
 
«От экспериментов с инфраструктурой до внедрения в продакшен»​
«От экспериментов с инфраструктурой до внедрения в продакшен»​«От экспериментов с инфраструктурой до внедрения в продакшен»​
«От экспериментов с инфраструктурой до внедрения в продакшен»​FDConf
 
Handling 10k requests per second with Symfony and Varnish - SymfonyCon Berlin...
Handling 10k requests per second with Symfony and Varnish - SymfonyCon Berlin...Handling 10k requests per second with Symfony and Varnish - SymfonyCon Berlin...
Handling 10k requests per second with Symfony and Varnish - SymfonyCon Berlin...Alexander Lisachenko
 
Micronaut For Single Page Apps
Micronaut For Single Page AppsMicronaut For Single Page Apps
Micronaut For Single Page AppsZachary Klein
 
Spring Booted, But... @JCConf 16', Taiwan
Spring Booted, But... @JCConf 16', TaiwanSpring Booted, But... @JCConf 16', Taiwan
Spring Booted, But... @JCConf 16', TaiwanPei-Tang Huang
 
Redux. From twitter hype to production
Redux. From twitter hype to productionRedux. From twitter hype to production
Redux. From twitter hype to productionFDConf
 
EWD 3 Training Course Part 39: Building a React.js application with QEWD, Part 3
EWD 3 Training Course Part 39: Building a React.js application with QEWD, Part 3EWD 3 Training Course Part 39: Building a React.js application with QEWD, Part 3
EWD 3 Training Course Part 39: Building a React.js application with QEWD, Part 3Rob Tweed
 
Design & Performance - Steve Souders at Fastly Altitude 2015
Design & Performance - Steve Souders at Fastly Altitude 2015Design & Performance - Steve Souders at Fastly Altitude 2015
Design & Performance - Steve Souders at Fastly Altitude 2015Fastly
 
Angular 2 Migration - JHipster Meetup 6
Angular 2 Migration - JHipster Meetup 6Angular 2 Migration - JHipster Meetup 6
Angular 2 Migration - JHipster Meetup 6William Marques
 
Easy Enterprise Integration Patterns with Apache Camel, ActiveMQ and ServiceMix
Easy Enterprise Integration Patterns with Apache Camel, ActiveMQ and ServiceMixEasy Enterprise Integration Patterns with Apache Camel, ActiveMQ and ServiceMix
Easy Enterprise Integration Patterns with Apache Camel, ActiveMQ and ServiceMixelliando dias
 
Composable and streamable Play apps
Composable and streamable Play appsComposable and streamable Play apps
Composable and streamable Play appsYevgeniy Brikman
 
N:1 Replication meets MHA
N:1 Replication meets MHAN:1 Replication meets MHA
N:1 Replication meets MHAdo_aki
 
"Service Worker: Let Your Web App Feel Like a Native "
"Service Worker: Let Your Web App Feel Like a Native ""Service Worker: Let Your Web App Feel Like a Native "
"Service Worker: Let Your Web App Feel Like a Native "FDConf
 
Node.js vs Play Framework (with Japanese subtitles)
Node.js vs Play Framework (with Japanese subtitles)Node.js vs Play Framework (with Japanese subtitles)
Node.js vs Play Framework (with Japanese subtitles)Yevgeniy Brikman
 
VCL template abstraction model and automated deployments to Fastly
VCL template abstraction model and automated deployments to FastlyVCL template abstraction model and automated deployments to Fastly
VCL template abstraction model and automated deployments to FastlyFastly
 
Spring Boot & WebSocket
Spring Boot & WebSocketSpring Boot & WebSocket
Spring Boot & WebSocketMing-Ying Wu
 
Puppet Camp London Fall 2015 - Service Discovery and Puppet
Puppet Camp London Fall 2015 - Service Discovery and PuppetPuppet Camp London Fall 2015 - Service Discovery and Puppet
Puppet Camp London Fall 2015 - Service Discovery and PuppetMarc Cluet
 
Migraine Drupal - syncing your staging and live sites
Migraine Drupal - syncing your staging and live sitesMigraine Drupal - syncing your staging and live sites
Migraine Drupal - syncing your staging and live sitesdrupalindia
 

La actualidad más candente (20)

Integration made easy with Apache Camel
Integration made easy with Apache CamelIntegration made easy with Apache Camel
Integration made easy with Apache Camel
 
«От экспериментов с инфраструктурой до внедрения в продакшен»​
«От экспериментов с инфраструктурой до внедрения в продакшен»​«От экспериментов с инфраструктурой до внедрения в продакшен»​
«От экспериментов с инфраструктурой до внедрения в продакшен»​
 
Serverless Java on Kubernetes
Serverless Java on KubernetesServerless Java on Kubernetes
Serverless Java on Kubernetes
 
Handling 10k requests per second with Symfony and Varnish - SymfonyCon Berlin...
Handling 10k requests per second with Symfony and Varnish - SymfonyCon Berlin...Handling 10k requests per second with Symfony and Varnish - SymfonyCon Berlin...
Handling 10k requests per second with Symfony and Varnish - SymfonyCon Berlin...
 
Micronaut For Single Page Apps
Micronaut For Single Page AppsMicronaut For Single Page Apps
Micronaut For Single Page Apps
 
Spring Booted, But... @JCConf 16', Taiwan
Spring Booted, But... @JCConf 16', TaiwanSpring Booted, But... @JCConf 16', Taiwan
Spring Booted, But... @JCConf 16', Taiwan
 
Redux. From twitter hype to production
Redux. From twitter hype to productionRedux. From twitter hype to production
Redux. From twitter hype to production
 
EWD 3 Training Course Part 39: Building a React.js application with QEWD, Part 3
EWD 3 Training Course Part 39: Building a React.js application with QEWD, Part 3EWD 3 Training Course Part 39: Building a React.js application with QEWD, Part 3
EWD 3 Training Course Part 39: Building a React.js application with QEWD, Part 3
 
Design & Performance - Steve Souders at Fastly Altitude 2015
Design & Performance - Steve Souders at Fastly Altitude 2015Design & Performance - Steve Souders at Fastly Altitude 2015
Design & Performance - Steve Souders at Fastly Altitude 2015
 
Angular beans
Angular beansAngular beans
Angular beans
 
Angular 2 Migration - JHipster Meetup 6
Angular 2 Migration - JHipster Meetup 6Angular 2 Migration - JHipster Meetup 6
Angular 2 Migration - JHipster Meetup 6
 
Easy Enterprise Integration Patterns with Apache Camel, ActiveMQ and ServiceMix
Easy Enterprise Integration Patterns with Apache Camel, ActiveMQ and ServiceMixEasy Enterprise Integration Patterns with Apache Camel, ActiveMQ and ServiceMix
Easy Enterprise Integration Patterns with Apache Camel, ActiveMQ and ServiceMix
 
Composable and streamable Play apps
Composable and streamable Play appsComposable and streamable Play apps
Composable and streamable Play apps
 
N:1 Replication meets MHA
N:1 Replication meets MHAN:1 Replication meets MHA
N:1 Replication meets MHA
 
"Service Worker: Let Your Web App Feel Like a Native "
"Service Worker: Let Your Web App Feel Like a Native ""Service Worker: Let Your Web App Feel Like a Native "
"Service Worker: Let Your Web App Feel Like a Native "
 
Node.js vs Play Framework (with Japanese subtitles)
Node.js vs Play Framework (with Japanese subtitles)Node.js vs Play Framework (with Japanese subtitles)
Node.js vs Play Framework (with Japanese subtitles)
 
VCL template abstraction model and automated deployments to Fastly
VCL template abstraction model and automated deployments to FastlyVCL template abstraction model and automated deployments to Fastly
VCL template abstraction model and automated deployments to Fastly
 
Spring Boot & WebSocket
Spring Boot & WebSocketSpring Boot & WebSocket
Spring Boot & WebSocket
 
Puppet Camp London Fall 2015 - Service Discovery and Puppet
Puppet Camp London Fall 2015 - Service Discovery and PuppetPuppet Camp London Fall 2015 - Service Discovery and Puppet
Puppet Camp London Fall 2015 - Service Discovery and Puppet
 
Migraine Drupal - syncing your staging and live sites
Migraine Drupal - syncing your staging and live sitesMigraine Drupal - syncing your staging and live sites
Migraine Drupal - syncing your staging and live sites
 

Similar a Reactive microservices with Micronaut - GR8Conf EU 2018

Developing Microservices using Spring - Beginner's Guide
Developing Microservices using Spring - Beginner's GuideDeveloping Microservices using Spring - Beginner's Guide
Developing Microservices using Spring - Beginner's GuideMohanraj Thirumoorthy
 
Webpack Encore Symfony Live 2017 San Francisco
Webpack Encore Symfony Live 2017 San FranciscoWebpack Encore Symfony Live 2017 San Francisco
Webpack Encore Symfony Live 2017 San FranciscoRyan Weaver
 
GWT Web Socket and data serialization
GWT Web Socket and data serializationGWT Web Socket and data serialization
GWT Web Socket and data serializationGWTcon
 
Greach 2019 - Creating Micronaut Configurations
Greach 2019 - Creating Micronaut ConfigurationsGreach 2019 - Creating Micronaut Configurations
Greach 2019 - Creating Micronaut ConfigurationsIván López Martín
 
Servlets 3.0 - Asynchronous, Extensibility, Ease-of-use @ JavaOne Brazil 2010
Servlets 3.0 - Asynchronous, Extensibility, Ease-of-use @ JavaOne Brazil 2010Servlets 3.0 - Asynchronous, Extensibility, Ease-of-use @ JavaOne Brazil 2010
Servlets 3.0 - Asynchronous, Extensibility, Ease-of-use @ JavaOne Brazil 2010Arun Gupta
 
Portable, secure, and lightweight: Wasm runtimes and their use-cases - Natali...
Portable, secure, and lightweight: Wasm runtimes and their use-cases - Natali...Portable, secure, and lightweight: Wasm runtimes and their use-cases - Natali...
Portable, secure, and lightweight: Wasm runtimes and their use-cases - Natali...Wey Wey Web
 
Patterns Are Good For Managers
Patterns Are Good For ManagersPatterns Are Good For Managers
Patterns Are Good For ManagersAgileThought
 
Rest web service_with_spring_hateoas
Rest web service_with_spring_hateoasRest web service_with_spring_hateoas
Rest web service_with_spring_hateoasZeid Hassan
 
Multi Client Development with Spring
Multi Client Development with SpringMulti Client Development with Spring
Multi Client Development with SpringJoshua Long
 
Carrying Enterprise on a Little Camel
Carrying Enterprise on a Little CamelCarrying Enterprise on a Little Camel
Carrying Enterprise on a Little CamelDimitry Pletnikov
 
Elastic and Cloud-ready Applications with Payara Micro
Elastic and Cloud-ready Applications with Payara MicroElastic and Cloud-ready Applications with Payara Micro
Elastic and Cloud-ready Applications with Payara MicroOndrej Mihályi
 
Elastic and Cloud-ready Applications with Payara Micro
Elastic and Cloud-ready Applications with Payara MicroElastic and Cloud-ready Applications with Payara Micro
Elastic and Cloud-ready Applications with Payara MicroPayara
 
Elastic and Cloud-ready Applications with Payara Micro
Elastic and Cloud-ready Applications with Payara MicroElastic and Cloud-ready Applications with Payara Micro
Elastic and Cloud-ready Applications with Payara MicroPayara
 
What’s new in cas 4.2
What’s new in cas 4.2 What’s new in cas 4.2
What’s new in cas 4.2 Misagh Moayyed
 
DevNexus 2020: Discover Modern Java
DevNexus 2020: Discover Modern JavaDevNexus 2020: Discover Modern Java
DevNexus 2020: Discover Modern JavaHenri Tremblay
 
Multi Client Development with Spring
Multi Client Development with SpringMulti Client Development with Spring
Multi Client Development with SpringJoshua Long
 
Highlights from Java 10, 11 and 12 and Future of Java at Javaland 2019 By Vad...
Highlights from Java 10, 11 and 12 and Future of Java at Javaland 2019 By Vad...Highlights from Java 10, 11 and 12 and Future of Java at Javaland 2019 By Vad...
Highlights from Java 10, 11 and 12 and Future of Java at Javaland 2019 By Vad...Vadym Kazulkin
 

Similar a Reactive microservices with Micronaut - GR8Conf EU 2018 (20)

Developing Microservices using Spring - Beginner's Guide
Developing Microservices using Spring - Beginner's GuideDeveloping Microservices using Spring - Beginner's Guide
Developing Microservices using Spring - Beginner's Guide
 
Webpack Encore Symfony Live 2017 San Francisco
Webpack Encore Symfony Live 2017 San FranciscoWebpack Encore Symfony Live 2017 San Francisco
Webpack Encore Symfony Live 2017 San Francisco
 
GWT Web Socket and data serialization
GWT Web Socket and data serializationGWT Web Socket and data serialization
GWT Web Socket and data serialization
 
Arquitecturas de microservicios - Medianet Software
Arquitecturas de microservicios   -  Medianet SoftwareArquitecturas de microservicios   -  Medianet Software
Arquitecturas de microservicios - Medianet Software
 
Greach 2019 - Creating Micronaut Configurations
Greach 2019 - Creating Micronaut ConfigurationsGreach 2019 - Creating Micronaut Configurations
Greach 2019 - Creating Micronaut Configurations
 
Servlets 3.0 - Asynchronous, Extensibility, Ease-of-use @ JavaOne Brazil 2010
Servlets 3.0 - Asynchronous, Extensibility, Ease-of-use @ JavaOne Brazil 2010Servlets 3.0 - Asynchronous, Extensibility, Ease-of-use @ JavaOne Brazil 2010
Servlets 3.0 - Asynchronous, Extensibility, Ease-of-use @ JavaOne Brazil 2010
 
Portable, secure, and lightweight: Wasm runtimes and their use-cases - Natali...
Portable, secure, and lightweight: Wasm runtimes and their use-cases - Natali...Portable, secure, and lightweight: Wasm runtimes and their use-cases - Natali...
Portable, secure, and lightweight: Wasm runtimes and their use-cases - Natali...
 
Patterns Are Good For Managers
Patterns Are Good For ManagersPatterns Are Good For Managers
Patterns Are Good For Managers
 
Intro to Laravel 4
Intro to Laravel 4Intro to Laravel 4
Intro to Laravel 4
 
Rest web service_with_spring_hateoas
Rest web service_with_spring_hateoasRest web service_with_spring_hateoas
Rest web service_with_spring_hateoas
 
Multi Client Development with Spring
Multi Client Development with SpringMulti Client Development with Spring
Multi Client Development with Spring
 
Carrying Enterprise on a Little Camel
Carrying Enterprise on a Little CamelCarrying Enterprise on a Little Camel
Carrying Enterprise on a Little Camel
 
Elastic and Cloud-ready Applications with Payara Micro
Elastic and Cloud-ready Applications with Payara MicroElastic and Cloud-ready Applications with Payara Micro
Elastic and Cloud-ready Applications with Payara Micro
 
Elastic and Cloud-ready Applications with Payara Micro
Elastic and Cloud-ready Applications with Payara MicroElastic and Cloud-ready Applications with Payara Micro
Elastic and Cloud-ready Applications with Payara Micro
 
Elastic and Cloud-ready Applications with Payara Micro
Elastic and Cloud-ready Applications with Payara MicroElastic and Cloud-ready Applications with Payara Micro
Elastic and Cloud-ready Applications with Payara Micro
 
What’s new in cas 4.2
What’s new in cas 4.2 What’s new in cas 4.2
What’s new in cas 4.2
 
DevNexus 2020: Discover Modern Java
DevNexus 2020: Discover Modern JavaDevNexus 2020: Discover Modern Java
DevNexus 2020: Discover Modern Java
 
Multi Client Development with Spring
Multi Client Development with SpringMulti Client Development with Spring
Multi Client Development with Spring
 
Highlights from Java 10, 11 and 12 and Future of Java at Javaland 2019 By Vad...
Highlights from Java 10, 11 and 12 and Future of Java at Javaland 2019 By Vad...Highlights from Java 10, 11 and 12 and Future of Java at Javaland 2019 By Vad...
Highlights from Java 10, 11 and 12 and Future of Java at Javaland 2019 By Vad...
 
Play Framework
Play FrameworkPlay Framework
Play Framework
 

Más de Alvaro Sanchez-Mariscal

Asynchronous and event-driven Grails applications
Asynchronous and event-driven Grails applicationsAsynchronous and event-driven Grails applications
Asynchronous and event-driven Grails applicationsAlvaro Sanchez-Mariscal
 
Creating applications with Grails, Angular JS and Spring Security - G3 Summit...
Creating applications with Grails, Angular JS and Spring Security - G3 Summit...Creating applications with Grails, Angular JS and Spring Security - G3 Summit...
Creating applications with Grails, Angular JS and Spring Security - G3 Summit...Alvaro Sanchez-Mariscal
 
Mastering Grails 3 Plugins - G3 Summit 2016
Mastering Grails 3 Plugins - G3 Summit 2016Mastering Grails 3 Plugins - G3 Summit 2016
Mastering Grails 3 Plugins - G3 Summit 2016Alvaro Sanchez-Mariscal
 
Desarrollo de aplicaciones con Grails 3, Angular JS y Spring Security
Desarrollo de aplicaciones con Grails 3, Angular JS y Spring SecurityDesarrollo de aplicaciones con Grails 3, Angular JS y Spring Security
Desarrollo de aplicaciones con Grails 3, Angular JS y Spring SecurityAlvaro Sanchez-Mariscal
 
Creating applications with Grails, Angular JS and Spring Security - GR8Conf U...
Creating applications with Grails, Angular JS and Spring Security - GR8Conf U...Creating applications with Grails, Angular JS and Spring Security - GR8Conf U...
Creating applications with Grails, Angular JS and Spring Security - GR8Conf U...Alvaro Sanchez-Mariscal
 
Mastering Grails 3 Plugins - GR8Conf US 2016
Mastering Grails 3 Plugins - GR8Conf US 2016Mastering Grails 3 Plugins - GR8Conf US 2016
Mastering Grails 3 Plugins - GR8Conf US 2016Alvaro Sanchez-Mariscal
 
Mastering Grails 3 Plugins - GR8Conf EU 2016
Mastering Grails 3 Plugins - GR8Conf EU 2016Mastering Grails 3 Plugins - GR8Conf EU 2016
Mastering Grails 3 Plugins - GR8Conf EU 2016Alvaro Sanchez-Mariscal
 
Creating applications with Grails, Angular JS and Spring Security - GR8Conf E...
Creating applications with Grails, Angular JS and Spring Security - GR8Conf E...Creating applications with Grails, Angular JS and Spring Security - GR8Conf E...
Creating applications with Grails, Angular JS and Spring Security - GR8Conf E...Alvaro Sanchez-Mariscal
 
Mastering Grails 3 Plugins - Greach 2016
Mastering Grails 3 Plugins - Greach 2016Mastering Grails 3 Plugins - Greach 2016
Mastering Grails 3 Plugins - Greach 2016Alvaro Sanchez-Mariscal
 
Creating applications with Grails, Angular JS and Spring Security
Creating applications with Grails, Angular JS and Spring SecurityCreating applications with Grails, Angular JS and Spring Security
Creating applications with Grails, Angular JS and Spring SecurityAlvaro Sanchez-Mariscal
 
Efficient HTTP applications on the JVM with Ratpack - Voxxed Days Berlin 2016
Efficient HTTP applications on the JVM with Ratpack - Voxxed Days Berlin 2016Efficient HTTP applications on the JVM with Ratpack - Voxxed Days Berlin 2016
Efficient HTTP applications on the JVM with Ratpack - Voxxed Days Berlin 2016Alvaro Sanchez-Mariscal
 
Efficient HTTP applications on the JVM with Ratpack - JDD 2015
Efficient HTTP applications on the JVM with Ratpack - JDD 2015Efficient HTTP applications on the JVM with Ratpack - JDD 2015
Efficient HTTP applications on the JVM with Ratpack - JDD 2015Alvaro Sanchez-Mariscal
 
Stateless authentication with OAuth 2 and JWT - JavaZone 2015
Stateless authentication with OAuth 2 and JWT - JavaZone 2015Stateless authentication with OAuth 2 and JWT - JavaZone 2015
Stateless authentication with OAuth 2 and JWT - JavaZone 2015Alvaro Sanchez-Mariscal
 
Stateless authentication for microservices - GR8Conf 2015
Stateless authentication for microservices - GR8Conf 2015Stateless authentication for microservices - GR8Conf 2015
Stateless authentication for microservices - GR8Conf 2015Alvaro Sanchez-Mariscal
 
Stateless authentication for microservices - Spring I/O 2015
Stateless authentication for microservices  - Spring I/O 2015Stateless authentication for microservices  - Spring I/O 2015
Stateless authentication for microservices - Spring I/O 2015Alvaro Sanchez-Mariscal
 
Stateless authentication for microservices - Greach 2015
Stateless authentication for microservices - Greach 2015Stateless authentication for microservices - Greach 2015
Stateless authentication for microservices - Greach 2015Alvaro Sanchez-Mariscal
 
Stateless authentication for microservices applications - JavaLand 2015
Stateless authentication for microservices applications -  JavaLand 2015Stateless authentication for microservices applications -  JavaLand 2015
Stateless authentication for microservices applications - JavaLand 2015Alvaro Sanchez-Mariscal
 

Más de Alvaro Sanchez-Mariscal (20)

Asynchronous and event-driven Grails applications
Asynchronous and event-driven Grails applicationsAsynchronous and event-driven Grails applications
Asynchronous and event-driven Grails applications
 
Practical Spring Cloud
Practical Spring CloudPractical Spring Cloud
Practical Spring Cloud
 
Creating applications with Grails, Angular JS and Spring Security - G3 Summit...
Creating applications with Grails, Angular JS and Spring Security - G3 Summit...Creating applications with Grails, Angular JS and Spring Security - G3 Summit...
Creating applications with Grails, Angular JS and Spring Security - G3 Summit...
 
Mastering Grails 3 Plugins - G3 Summit 2016
Mastering Grails 3 Plugins - G3 Summit 2016Mastering Grails 3 Plugins - G3 Summit 2016
Mastering Grails 3 Plugins - G3 Summit 2016
 
Desarrollo de aplicaciones con Grails 3, Angular JS y Spring Security
Desarrollo de aplicaciones con Grails 3, Angular JS y Spring SecurityDesarrollo de aplicaciones con Grails 3, Angular JS y Spring Security
Desarrollo de aplicaciones con Grails 3, Angular JS y Spring Security
 
Creating applications with Grails, Angular JS and Spring Security - GR8Conf U...
Creating applications with Grails, Angular JS and Spring Security - GR8Conf U...Creating applications with Grails, Angular JS and Spring Security - GR8Conf U...
Creating applications with Grails, Angular JS and Spring Security - GR8Conf U...
 
Mastering Grails 3 Plugins - GR8Conf US 2016
Mastering Grails 3 Plugins - GR8Conf US 2016Mastering Grails 3 Plugins - GR8Conf US 2016
Mastering Grails 3 Plugins - GR8Conf US 2016
 
Mastering Grails 3 Plugins - GR8Conf EU 2016
Mastering Grails 3 Plugins - GR8Conf EU 2016Mastering Grails 3 Plugins - GR8Conf EU 2016
Mastering Grails 3 Plugins - GR8Conf EU 2016
 
Creating applications with Grails, Angular JS and Spring Security - GR8Conf E...
Creating applications with Grails, Angular JS and Spring Security - GR8Conf E...Creating applications with Grails, Angular JS and Spring Security - GR8Conf E...
Creating applications with Grails, Angular JS and Spring Security - GR8Conf E...
 
Mastering Grails 3 Plugins - Greach 2016
Mastering Grails 3 Plugins - Greach 2016Mastering Grails 3 Plugins - Greach 2016
Mastering Grails 3 Plugins - Greach 2016
 
Creating applications with Grails, Angular JS and Spring Security
Creating applications with Grails, Angular JS and Spring SecurityCreating applications with Grails, Angular JS and Spring Security
Creating applications with Grails, Angular JS and Spring Security
 
Efficient HTTP applications on the JVM with Ratpack - Voxxed Days Berlin 2016
Efficient HTTP applications on the JVM with Ratpack - Voxxed Days Berlin 2016Efficient HTTP applications on the JVM with Ratpack - Voxxed Days Berlin 2016
Efficient HTTP applications on the JVM with Ratpack - Voxxed Days Berlin 2016
 
Efficient HTTP applications on the JVM with Ratpack - JDD 2015
Efficient HTTP applications on the JVM with Ratpack - JDD 2015Efficient HTTP applications on the JVM with Ratpack - JDD 2015
Efficient HTTP applications on the JVM with Ratpack - JDD 2015
 
Stateless authentication with OAuth 2 and JWT - JavaZone 2015
Stateless authentication with OAuth 2 and JWT - JavaZone 2015Stateless authentication with OAuth 2 and JWT - JavaZone 2015
Stateless authentication with OAuth 2 and JWT - JavaZone 2015
 
Stateless authentication for microservices - GR8Conf 2015
Stateless authentication for microservices - GR8Conf 2015Stateless authentication for microservices - GR8Conf 2015
Stateless authentication for microservices - GR8Conf 2015
 
Ratpack 101 - GR8Conf 2015
Ratpack 101 - GR8Conf 2015Ratpack 101 - GR8Conf 2015
Ratpack 101 - GR8Conf 2015
 
Ratpack 101 - GeeCON 2015
Ratpack 101 - GeeCON 2015Ratpack 101 - GeeCON 2015
Ratpack 101 - GeeCON 2015
 
Stateless authentication for microservices - Spring I/O 2015
Stateless authentication for microservices  - Spring I/O 2015Stateless authentication for microservices  - Spring I/O 2015
Stateless authentication for microservices - Spring I/O 2015
 
Stateless authentication for microservices - Greach 2015
Stateless authentication for microservices - Greach 2015Stateless authentication for microservices - Greach 2015
Stateless authentication for microservices - Greach 2015
 
Stateless authentication for microservices applications - JavaLand 2015
Stateless authentication for microservices applications -  JavaLand 2015Stateless authentication for microservices applications -  JavaLand 2015
Stateless authentication for microservices applications - JavaLand 2015
 

Último

Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
Active Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdfActive Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdfCionsystems
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfkalichargn70th171
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
Test Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendTest Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendArshad QA
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️anilsa9823
 

Último (20)

Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Active Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdfActive Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdf
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
Test Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendTest Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and Backend
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 

Reactive microservices with Micronaut - GR8Conf EU 2018

  • 1. Reactive microservices with Micronaut Álvaro Sánchez-Mariscal @alvaro_sanchez
  • 2. About me — Coming from Madrid ! — Developer since 2001 (Java / Spring stack). — Grails fanboy since v0.4. — Working @ OCI since 2015: Groovy, Grails & Micronaut! — Father since 2017! " @alvaro_sanchez
  • 5.  Introducing Micronaut The productivity of Grails with the performance of a compile-time, non-blocking framework. — Designed from the ground up with microservices and the cloud in mind. — Ultra-lightweight and Reactive (based on Netty) — Integrated AOP and Compile-Time DI for Java, Groovy and Kotlin. — HTTP Client & Server. @alvaro_sanchez
  • 6. Reactive microservices — Any Reactive Streams implementation: — RxJava 2.x. — Reactor 3.x. — Akka. — Plain old java.util.concurrent.CompletableFuture. @alvaro_sanchez
  • 7. Micronaut is small and fast! — JAR files: 8Mb (Java) / 12Mb (Groovy). — Spring+Groovy: 36MB / Grails: 27Mb. — Heap size: 7Mb (Java) / 19Mb (Groovy). — Spring+Groovy: 33Mb / Grails: 49Mb. — Startup time: ~1 second. — Spring / Grails: ~3-4 seconds. @alvaro_sanchez
  • 11. Inversion of Control / Dependency Injection — Inspired from Spring. — Compile-time: no reflection, no runtime proxies. — JSR-330 (javax.inject) or Spring-like annotations. — Implemented via annotation processors (Java and Kotlin) and AST transformations (Groovy) that use ASM to generate bytecode. @alvaro_sanchez
  • 12. interface Engine { String start() } @Singleton class V8Engine implements Engine { String start() { "Starting V8" } } @Singleton class Vehicle { final Engine engine @Inject Vehicle(Engine engine) { this.engine = engine } String start() { engine.start() // "Starting V8" } } @alvaro_sanchez
  • 13. Injectable types — An Optional of a bean. If the bean doesn’t exist empty() is injected. Alternatively, use @Nullable. — An Iterable or subtype of Iterable (eg List, Collection etc). — A lazy Stream of beans. — A native array of beans of a given type (Engine[]). — A javax.inject.Provider if a circular dependency requires it. @alvaro_sanchez
  • 14. Bean qualifiers @Singleton class V6Engine implements Engine { ... } @Singleton class V8Engine implements Engine { ... } //Vehicle constructor @Inject Vehicle(@Named('v8') Engine engine) { this.engine = engine } @alvaro_sanchez
  • 15. Bean qualifiers @Qualifier @Retention(RUNTIME) @interface V8 { } //Vehicle constructor @Inject Vehicle(@V8 Engine engine) { this.engine = engine } @alvaro_sanchez
  • 16. Refreshable beans @Refreshable class WeatherService { String forecast @PostConstruct void init() { forecast = "Scattered Clouds ${new Date().format('dd/MMM/yy HH:ss.SSS')}" } String latestForecast() { return forecast } } @alvaro_sanchez
  • 17. Refreshable beans @Controller('/weather') class WeatherController { @Inject WeatherService weatherService ... } — Refreshable via: — The /refresh endpoint. — applicationContext.publishEvent(new RefreshEvent()) @alvaro_sanchez
  • 18. Refreshing upon config changes @Bean(preDestroy = "close") @Refreshable('mongodb') MongoClient mongoClient(ReactiveMongoConfiguration rmc) { return MongoClients.create(rmc.buildSettings()) } @alvaro_sanchez
  • 19.  Bean factories @Singleton class CrankShaft {} @Factory class EngineFactory { @Bean @Singleton Engine v8Engine(CrankShaft crankShaft) { new V8Engine(crankShaft) } } @alvaro_sanchez
  • 20.  Conditional beans @Singleton @Requires(beans = DataSource) @Requires(property = "datasource.url") class JdbcBookService implements BookService { DataSource dataSource public JdbcBookService(DataSource dataSource) { this.dataSource = dataSource } } @alvaro_sanchez
  • 21.  Conditional beans @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.PACKAGE, ElementType.TYPE}) @Requires(beans = DataSource) @Requires(property = "datasource.url") @interface RequiresJdbc { } @RequiresJdbc class JdbcBookService implements BookService { ... } @alvaro_sanchez
  • 22.  Supported conditions — @Requires(classes=javax.servlet.Servlet) — @Requires(beans=javax.sql.DataSource) — @Requires(env='TRAVIS') — @Requires(configuration='foo.bar') — @Requires(sdk=Sdk.JAVA, value="1.8") — @Requires(property='consul.enabled', value="true", defaultValue="false") @alvaro_sanchez
  • 23.  Bean configurations — Grouping of multiple bean definitions within a package: //file: src/main/groovy/com/example/json/package-info.groovy @Configuration @Requires(classes = com.fasterxml.jackson.databind.ObjectMapper) package com.example.json — All the beans from the package can be required with @Requires(configuration='com.example.json') @alvaro_sanchez
  • 24. Life-cycle methods and events — javax.annotation.PostConstruct is supported. — For events: @Singleton class EngineInitializer implements BeanInitializedEventListener<EngineFactory> { @Override EngineFactory onInitialized(BeanInitializingEvent<EngineFactory> event) { EngineFactory engineFactory = event.bean engineFactory.rodLength = 6.6 return event.bean } } @alvaro_sanchez
  • 26. PropertySources — Command line arguments. — Properties from SPRING_APPLICATION_JSON (for Spring compatibility). — Properties from MICRONAUT_APPLICATION_JSON. — Java System Properties. — OS environment variables. — Enviroment-specific properties from application-{environment}. {extension}. — (Either .properties, .json, .yml or .groovy formats supported) — Application-specific properties from application.{extension}. @alvaro_sanchez
  • 27.  Injecting configuration values @Singleton class EngineImpl implements Engine { @Value('${my.engine.cylinders:6}') int cylinders } @alvaro_sanchez
  • 28.  @EachProperty @EachProperty("myapp.datasources") public class DataSourceConfiguration { final String name final URI url } //src/main/resources/application.properties myapp.datasources.one = "jdbc:mysql://localhost/one" myapp.datasources.two = "jdbc:mysql://localhost/two" @alvaro_sanchez
  • 29.  @EachBean @Factory class DataSourceFactory { @EachBean(DataSourceConfiguration) DataSource dataSource(DataSourceConfiguration cfg) { URI url = cfg.url return new DataSource(url) } } @alvaro_sanchez
  • 30.  Type-safe @ConfigurationProperties @ConfigurationProperties('my.engine') class EngineConfig { @NotBlank String manufacturer = "Ford" @Min(1L) int cylinders CrankShaft crankShaft = new CrankShaft() @ConfigurationProperties('crank-shaft') static class CrankShaft { Optional<Double> rodLength = Optional.empty() } } @alvaro_sanchez
  • 32.  Type-safe @ConfigurationProperties — Simple injection: @Singleton class EngineImpl implements Engine { final EngineConfig config EngineImpl(EngineConfig config) { //Implicit injection this.config = config } } @alvaro_sanchez
  • 33. AOP
  • 34. Micronaut's AOP — Around Advice - decorates a method or class. — Trace logging. — Hystrix support. — Cache abstraction. — Circuit breaker pattern with retry support. — Validation. — Introduction Advice - introduces new behaviour to a class. — HTTP client. @alvaro_sanchez
  • 35. Cache abstraction @Singleton @CacheConfig("pets") class PetService { @Cacheable Pet findById(Long id) { ... } @CachePut void save(Pet pet) { ... } @CacheInvalidate void delete(Pet pet) { ... } } @alvaro_sanchez
  • 37. Hello World //src/main/java/example/Application.java public class Application { public static void main(String[] args) { Micronaut.run(Application.class); } } @alvaro_sanchez
  • 38. Hello World //src/main/java/example/HelloController.java @Controller("/") public class HelloController { @Get("/hello/{name}") public Single<String> hello(@NotBlank String name) { return Single.just("Hello " + name + "!"); } } @alvaro_sanchez
  • 39. Testing with Spock class HelloControllerSpec extends Specification { @Shared @AutoCleanup EmbeddedServer embeddedServer = ApplicationContext.run(EmbeddedServer) @Shared @AutoCleanup HttpClient client = HttpClient.create(embeddedServer.URL) void "test hello world response"() { expect: client.toBlocking() .retrieve(HttpRequest.GET('/hello/Greach')) == "Hello Greach!" } } @alvaro_sanchez
  • 40. Testing with JUnit public class HelloWorldTest { private static EmbeddedServer server; private static HttpClient client; @BeforeClass public static void setupServer() { server = ApplicationContext.run(EmbeddedServer.class); client = server.getApplicationContext().createBean(HttpClient.class, server.getURL()); } @AfterClass public static void stopServer() { if(server != null) { server.stop(); } if(client != null) { client.stop(); } } @Test public void testHelloWorkd() throws Exception { String body = client.toBlocking().retrieve("/hello/Greach"); assertEquals(body, "Hello Greach!"); } } @alvaro_sanchez
  • 41. Declarative routing //Both are equivalent @Get("/hello") String hello() { return "Hello World" } @Get String hello() { return "Hello World" } @alvaro_sanchez
  • 42. Programmatic routing @Singleton public class MyRoutes extends DefaultRouteBuilder { public MyRoutes(ApplicationContext beanContext) { super(beanContext); } @Inject void someRoutes(BookController controller, AuthorController authorController) { GET("/conditional{/message}", controller, "hello", String.class) .where((request)-> request.getContentType() .map(type->type.equals(MediaType.APPLICATION_JSON_TYPE)) .orElse(false) ); GET("/message{/message}", controller, "hello", String.class).consumes(MediaType.APPLICATION_JSON_TYPE); GET("/books{/id}", controller, "show").nest(() -> GET("/authors", controller) ); } } @alvaro_sanchez
  • 43. Request binding — Body: String hello(@Body String body) — Cookies: String hello(@CookieValue String myCookie) — Headers: String hello(@Header String contentType) — Parameters: String hello(@Parameter String myParam) — Special cases: — String hello(@Header Optional<String> contentType) — String hello(@Parameter ZonedDateTime date) @alvaro_sanchez
  • 44. Direct request/response manipulation @Get("/hello") HttpResponse<String> hello(HttpRequest<?> request) { String name = request.getParameters() .getFirst("name") .orElse("Nobody"); return HttpResponse.ok("Hello " + name + "!!") .header("X-My-Header", "Foo"); } @alvaro_sanchez
  • 45. Reactive request processing @Post(consumes = MediaType.TEXT_PLAIN) Single<MutableHttpResponse<String>> echoFlow(@Body Flowable<String> text) { return text.collect(StringBuffer::new, StringBuffer::append) .map(buffer -> HttpResponse.ok(buffer.toString()) ); } @alvaro_sanchez
  • 46. Reactive responses — Any type that implements the org.reactivestreams.Publisher: Flowable<String> hello() {} — A Java's CompletableFuture instance: CompletableFuture<String> hello() {} — An io.micronaut.http.HttpResponse and optional response body: HttpResponse<Flowable<String>> hello() {} @alvaro_sanchez
  • 47. Non-reactive responses — Any implementation of CharSequence: String hello() — Any simple POJO type Book show() @alvaro_sanchez
  • 48. Threading model The response type determines the thread pool used to execute the request: — Non-blocking requests will be executed in the Netty event loop thread pool. — Blocking requests will be executed on the I/O thread pool. @alvaro_sanchez
  • 49. Reactive JSON parsing with Jackson @Post public Single<HttpResponse<Person>> save(@Body Single<Person> person) { return person.map(p -> { //do something blocking, and then: return HttpResponse.created(p); } ); } @alvaro_sanchez
  • 50. Non-reactive JSON parsing If your method does not do any blocking I/O: @Post public HttpResponse<Person> save(@Body Person person) { //do something, and then: return HttpResponse.created(person); } @alvaro_sanchez
  • 52.  Basics //src/main/groovy/example/HelloController.groovy @Controller("/") class HelloController { @Get("/hello/{name}") String hello(String name) { return "Hello $name!" } } //src/test/groovy/example/HelloClient.groovy @Client('/') interface HelloClient { @Get("/hello/{name}") String hello(String name) } @alvaro_sanchez
  • 53.  Testing it class HelloControllerSpec extends Specification { @Shared @AutoCleanup EmbeddedServer embeddedServer = ApplicationContext.run(EmbeddedServer) void "test hello world"() { given: HelloClient client = embeddedServer.applicationContext.getBean(HelloClient) expect: client.hello("Fred") == "Hello Fred!" } } @alvaro_sanchez
  • 54.  Features — Service discovery aware: Consul and Eureka support. — Load balancing: round robin, Netflix's Ribbon. — Reactive: based on the return types. — Fault tolerant: retry, fallback, circuit breaker. @alvaro_sanchez
  • 55. Fallback support @Validated interface PetOperations<T extends Pet> { @Get("/") Single<List<T>> list() } @Client(id = "pets", path = "/v1/pets") interface PetClient extends PetOperations<Pet> { @Get("/") Single<List<Pet>> findAll() } @Fallback class PetClientFallback implements PetOperations<Pet> { Single<List<Pet>> list() { Single.just([] as List<Pet>) } } @alvaro_sanchez
  • 56. Retry / circuit breaker support @Client("/dodgy-api") @Retryable(attempts = '5', delay = '5ms') interface ApiClient { ... } @Singleton @CircuitBreaker(attempts = '5', delay = '5ms', reset = '300ms') class MyService { ... } @alvaro_sanchez
  • 57. Retryable beans @Singleton class Neo4jDriverBuilder { @Retryable(ServiceUnavailableException) Driver buildDriver() { //build driver } } @alvaro_sanchez
  • 59. Simple functions as Groovy scripts @Field @Inject Twitter twitterClient @CompileStatic UpdateResult updateStatus(Message status) { Status s = twitterClient.updateStatus(status.text) URL url= new URL("https://twitter.com/$s.user.screenName/status/${s.id}") return new UpdateResult(url, s.createdAt.time) } @alvaro_sanchez
  • 60. Or with function beans import java.util.function.Function @FunctionBean('book') class BookFunction implements Function<Book, Book> { @Override Book apply(Book book) { book.title = book.title.toUpperCase() return book } } @alvaro_sanchez
  • 61. Function clients @FunctionClient interface TweetClient { Single<Result> updateStatus(String text) static class Result { URL url } } @alvaro_sanchez
  • 62. Testing: directly void "run function directly"() { expect: new HelloWorldFunction() .hello(new Person(name: "Fred")) .text == "Hello Fred!" } @alvaro_sanchez
  • 63. Testing: REST void "run function as REST service"() { given: EmbeddedServer server = ApplicationContext.run(EmbeddedServer) HelloClient client = server.getApplicationContext().getBean(HelloClient) when: Message message = client.hello("Fred").blockingGet() then: message.text == "Hello Fred!" } @alvaro_sanchez
  • 64.  Testing: AWS Lambda void "run execute function as lambda"() { given: ApplicationContext applicationContext = ApplicationContext.run( 'aws.lambda.functions.hello.functionName':'hello-world', 'aws.lambda.region':'us-east-1' ) HelloClient client = applicationContext.getBean(HelloClient) when: Message message = client.hello("Fred").blockingGet() then: message.text == "Hello Fred!" } @alvaro_sanchez
  • 66. Error handling with @Error @Controller class TestController { @Get HttpResponse bad() { HttpResponse.badRequest() } @Error(status = HttpStatus.BAD_REQUEST) HttpResponse badHandler() { HttpResponse.status(HttpStatus.BAD_REQUEST, "You sent me bad stuff") } } @alvaro_sanchez
  • 67. Error handling with @Error — Handling exceptions: — @Error(JsonParseException) — Global error handling: — @Error @alvaro_sanchez
  • 68. Request / response filters @Filter("/hello/**") public class TraceFilter implements HttpServerFilter { @Override public Publisher<MutableHttpResponse<?>> doFilter(HttpRequest<?> request, ServerFilterChain chain) { return traceService.trace(request) .switchMap(aBoolean -> chain.proceed(request)) .doOnNext(res -> res.getHeaders().add("X-Trace-Enabled", "true") ); } } @alvaro_sanchez
  • 69. Security solution import io.micronaut.http.annotation.*; import io.micronaut.security.Secured; import java.security.Principal; @Secured("isAuthenticated()") @Controller("/") public class HomeController { @Get("/") String index(Principal principal) { return "Welcome, " + principal.getName(); } } @alvaro_sanchez
  • 70. CLI [~]$ sdk install micronaut ... [~]$ mn create-service teams-api -build=maven -features=discovery-consul,security-jwt | Service created at /tmp/teams-api [teams-api]$ mn create-controller player | Rendered template Controller.java to destination src/main/java/teams/api/PlayerController.java | Rendered template ControllerTest.java to destination src/test/java/teams/api/PlayerControllerTest.java @alvaro_sanchez
  • 71. And much more! — HTTP Server: SSL, CORS, Server-Sent Events. — Production endpoints: /beans, /info, /health, / refresh, /routes, /stop — Service Discovery: Consul, Eureka, Kubernetes, AWS Route 53, Ribbon. — Distributed tracing: Zipkin, Jaeger. — Data access: SQL, Hibernate, MongoDB, Neo4j, Redis, Cassandra, Kafka, RabbitMQ. @alvaro_sanchez
  • 72. A!ending to the workshop? http://bit.ly/mn-workshop @alvaro_sanchez
  • 73. Q & A Álvaro Sánchez-Mariscal @alvaro_sanchez