Slide 1

Slide 1 text

@fstabr #Devoxx #unrestful unRESTful Web Services with HTTP/2 Fabian Stäber ConSol* Software GmbH

Slide 2

Slide 2 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c Contents • HTTP/2 Intro -> My First HTTP/2 Request • HTTP/2 new Features and how to use them in Java •  Multiplexing •  Server Push •  Stream Priorization and Flow Control • Testing HTTP/2-based REST services

Slide 3

Slide 3 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c HTTP/2 is already here! Browsers Java Servers Non-Java Servers Apache mod_h[ttp]2

Slide 4

Slide 4 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c Timeline 2009 1991 1996 1999 2015

Slide 5

Slide 5 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c Why HTTP/2? HTTP/2 is all about reducing latency: • Less protocol overhead • Header compression • Multiplexing • Request Priorization • Server Push

Slide 6

Slide 6 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c Compatibility with HTTP/1 HTTP/2 does not break the Web • Same semantics as HTTP/1 •  Request/response based communication •  HTTP Sessions and cookies • Goal: Any HTTP/1 application can be deployed on an HTTP/2 server without code change.

Slide 7

Slide 7 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c A First HTTP/2 Request Client GET / Server

Slide 8

Slide 8 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c Switching Protocol with HTTP/1 Client Server TCP Connection SSL Handshake Ilya Grigorik hpbn.co HTTP/1 Upgrade Other Protocol, e.g. WebSocket

Slide 9

Slide 9 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c Switching Protocol with HTTP/2 Client Server TCP Connection SSL Handshake + ALPN Ilya Grigorik hpbn.co Other Protocol, e.g. HTTP/2

Slide 10

Slide 10 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c • SSL is implemented in the JRE in package sun.security.ssl • Jetty provides ALPN version of sun.security.ssl for many OpenJDK 7 and 8 releases • Must start Java with VM parameter -Xbootclasspath/p:alpn-boot-VERSION.jar • ALPN will be part of Java 9 with JEP 244 Application Layer Protocol Negotiation ALPN

Slide 11

Slide 11 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) { resp.setContentType("text/plain"); resp.getWriter().write("Hello, World!"); } demo My First HTTP/2 Request: Example Servlet

Slide 12

Slide 12 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c demo My First HTTP/2 Request: Server git clone https://github.com/fstab/http2-examples cd http2-examples/jetty-http2-server-example mvn package wget http://repo1.maven.org/maven2/org/mortbay/jetty/alpn/\ > alpn-boot/8.1.5.v20150921/alpn-boot-8.1.5.v20150921.jar java -Xbootclasspath/p:alpn-boot-8.1.5.v20150921.jar \ > -jar target/jetty-http2-server-example.jar

Slide 13

Slide 13 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c • HTTP/2 is binary – telnet won‘t help • The curl command doesn‘t support server push messages yet. • Wrote my own little tool: https://github.com/fstab/h2c • h2c start –dump • h2c get https://localhost:8443 demo My First HTTP/2 Request: Client

Slide 14

Slide 14 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c HTTP/2 output vs HTTP/1 output GET / HTTP/1.1 Host: localhost:8443 HTTP/1.1 200 OK Server: Jetty(9.3.3v20150827) Date: Fri, 16 Oct 2015 16:30:35 GMT Content-Type: text/plain;charset=iso-8859-1 {13 bytes}

Slide 15

Slide 15 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c HTTP/2 output vs HTTP/1 output -> HEADERS(3) + END_STREAM + END_HEADERS :method: GET :scheme: https :authority: localhost:8443 :path: / <- HEADERS(3) - END_STREAM + END_HEADERS :status: 200 server: Jetty(9.3.3.v20150827) date: Fri, 16 Oct 2015 16:30:35 GMT content-type: text/plain;charset=iso-8859-1 <- DATA(3) + END_STREAM {13 bytes}

Slide 16

Slide 16 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c HTTP/2 output vs HTTP/1 output

Slide 17

Slide 17 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c GET /8-things-about-couchbase/ HTTP/1.1 Host: blog.arungupta.me Connection: keep-alive Cache-Control: max-age=0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36 Referer: http://blog.arungupta.me/couchbase-javaone-2015/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed% 3A+MilesToGo+%28Miles+to+go+2.0%29 Accept-Encoding: gzip, deflate, sdch Accept-Language: en-US,en;q=0.8,de;q=0.6,fr;q=0.4 Cookie: PHPSESSID=trr42cnr1u2ugekervdnkb4kc2; NCS_INENTIM=1445065465; JCS_INENREF=http%3A//t.co/UlzEpBg7wx; J CS_INENTIM=1445065466166; 1919598ddf048ef8060898ffee630b16=7bc66ae543ca8e475a2ec85a9c2e7d49; SJECT15=CKON1 5; __utma=202419266.948108038.1445065466.1445065466.1445065466.1; __utmb=202419266.2.10.1445065466; __utmc=202 419266; __utmz=202419266.1445065466.1.1.utmcsr=feedburner|utmccn=Feed:%20MilesToGo%20(Miles%20to%20go%202.0)|ut mcmd=feed Header Compression HPACK

Slide 18

Slide 18 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c Contents • HTTP/2 Intro -> My First HTTP/2 Request • HTTP/2 new Features and how to use them in Java •  Multiplexing •  Server Push •  Stream Priorization and Flow Control • Testing HTTP/2-based REST services

Slide 19

Slide 19 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c Multiplexing • Goal: Make Web Sites faster • Demo: https:// http2.golang.org/ gophertiles demo

Slide 20

Slide 20 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c demo Multiplexing for REST: Non-Blocking Services git clone https://github.com/fstab/http2-examples.git cd http2-examples/multiplexing-examples mvn package wget http://repo1.maven.org/maven2/org/mortbay/jetty/alpn/\ > alpn-boot/8.1.5.v20150921/alpn-boot-8.1.5.v20150921.jar java -Xbootclasspath/p:alpn-boot-8.1.5.v20150921.jar \ > -jar server/target/server.jar java -Xbootclasspath/p:alpn-boot-8.1.5.v20150921.jar \ > -jar okhttp-client/target/okhttp-client.jar

Slide 21

Slide 21 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) { // ... sleep(SECONDS.toMillis(6)); // ... } demo Multiplexing for REST: Non-Blocking Services

Slide 22

Slide 22 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c HTTP URL Connection ... and is synchronous! Does not support HTTP/2 ... private void sendGet() throws Exception { URL url = new URL("https://www.twitter.com"); HttpURLConnection con = (HttpURLConnection) url.openConnection(); try (BufferedReader in = new BufferedReader( new InputStreamReader(con.getInputStream()))) { String line; while ((line = in.readLine()) != null) { System.out.println(line); } } }

Slide 23

Slide 23 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c OkHttp Request request = new Request.Builder() .url("https://localhost:8443") .build(); client.newCall(request).enqueue(new Callback() { public void onResponse(Response response) throws IOException { // do something with response.body() } });

Slide 24

Slide 24 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c Netty FullHttpRequest request = new DefaultFullHttpRequest(HTTP_1_1, GET, ""); request.headers().addObject(HOST, URI.create("https://localhost:8443")); channel.writeAndFlush(request); public class HttpResponseHandler extends SimpleChannelInboundHandler { @Override protected void messageReceived( ChannelHandlerContext ctx, FullHttpResponse msg) throws Exception { // Do something with msg.content() ChannelPromise promise = streamidPromiseMap.get(streamId); promise.setSuccess(); } }

Slide 25

Slide 25 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c Jetty MetaData.Request request = new MetaData.Request( "GET", new HttpURI("https://localhost:8443/"), HTTP_2, requestFields); HeadersFrame headersFrame = new HeadersFrame(request, null, true); session.newStream(headersFrame, new FuturePromise<>(), responseListener); f Stream.Listener responseListener = new Stream.Listener.Adapter() { @Override public void onData(Stream stream, DataFrame frame, Callback callback) { // do something with frame.getData() callback.succeeded(); } };

Slide 26

Slide 26 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c Upcoming Standard Libraries • Java SE: new HttpUrlConnection JEP 110 • (Java EE: JAX-RS Client API ???)

Slide 27

Slide 27 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c Contents • HTTP/2 Intro -> My First HTTP/2 Request • HTTP/2 new Features and how to use them in Java •  Multiplexing •  Server Push •  Stream Priorization and Flow Control • HTTP/2 Client How-To

Slide 28

Slide 28 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c Push What it looks like: •  Request sent from client to server What actually happens: •  Push promise sent from server to client HTTP/2 is not a replacement for WebSockets.

Slide 29

Slide 29 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c Implicit Push for Web Servers How Web Servers use Push for delivering Web Pages: • For generated content (JSF): Should be possible to know which resources need to be pushed • For static content (HTML, Angular, ...): Learn from REFERER header (example included in Jetty as servlet filter).

Slide 30

Slide 30 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c Push and REST Example: How to trigger a push request in the Jetty server: Will be standardized with Servlet 4.0 !!! Request baseRequest = Request.getBaseRequest(req); if (baseRequest.isPushSupported()) { baseRequest .getPushBuilder() .method("GET") .path("/data") .push(); }

Slide 31

Slide 31 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c Push and REST Receive push request in client: Perform regular GET request, will be responded from the cache. HOWEVER: Client can be notified about the available response in an onPush() callback.

Slide 32

Slide 32 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c Push and REST Efficient Polling with HTTP/2 Server Push: • REST interface where client polls a resource • In case Server Push is supported, client polls not by time interval but polling is triggered by push message. • Fully compatible with REST semantics but much more efficient than polling with HTTP/1. • Makes workarounds like long polling, websockets, etc. obosolete.

Slide 33

Slide 33 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c demo Push and REST git clone https://github.com/fstab/http2-examples.git cd http2-examples/jetty-http2-echo-server mvn package java -Xbootclasspath/p:alpn-boot-8.1.5.v20150921.jar \ > -jar target/jetty-http2-echo-server.jar h2c start --dump h2c post --data 'hello' https://localhost:8443/data h2c get https://localhost:8443/data

Slide 34

Slide 34 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c Push Demo <- PUSH_PROMISE(1) + END_HEADERS Promised Stream Id: 2 :scheme: https :method: GET :authority: localhost:8443 :path: /data content-length: 12 host: localhost:8443 x-http2-push: PushBuilder referer: https://localhost:8443/data demo

Slide 35

Slide 35 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c Contents • HTTP/2 Intro -> My First HTTP/2 Request • HTTP/2 new Features and how to use them in Java •  Multiplexing •  Server Push •  Stream Priorization and Flow Control • Testing HTTP/2-based REST services

Slide 36

Slide 36 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c Stream Priorization • HEADERS frame may contain stream dependency • PRIORITY frame contains Weight field • Api planned in Servlet 4.0 A B C

Slide 37

Slide 37 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c Flow Control • Based on WINDOW_UPDATE frames • Send up to n Bytes, then wait for WINDOW_UPDATE public interface FlowControlStrategy { public static int DEFAULT_WINDOW_SIZE = 65535; public void onDataReceived(ISession session, IStream stream, int length); public void onDataConsumed(ISession session, IStream stream, int length); public void onDataSent(IStream stream, int length); public void onSessionStalled(ISession session); public void onStreamStalled(IStream stream); // ... }

Slide 38

Slide 38 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c Contents • HTTP/2 Intro -> My First HTTP/2 Request • HTTP/2 new Features and how to use them in Java •  Multiplexing •  Server Push •  Stream Priorization and Flow Control • Testing HTTP/2-based REST services

Slide 39

Slide 39 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c Testing with Arquillian Cube https://dockerHost:2376 wildfly-docker: image: fstab/wildfly-http2:9.0.1.Final await: strategy: polling sleepPollingTime: 1000 iterations: 120 portBindings: ["8443", "9990"]

Slide 40

Slide 40 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c Testing with Arquillian Cube dockerServerIp 9990 admin admin

Slide 41

Slide 41 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c Testing with rhuss/docker-maven-plugin org.jolokia docker-maven-plugin ${project.version}

Slide 42

Slide 42 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c Testing with rhuss/docker-maven-plugin pre-integration-test stop post-integration-test

Slide 43

Slide 43 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c Testing with OkHttp MockWebServer @Test public void test() throws Exception { MockWebServer server = new MockWebServer(); SSLContext sslContext = new SslContextBuilder(getLocalHost().getHostName()).build(); server.useHttps(sslContext.getSocketFactory(), false); server.enqueue(new MockResponse().setBody("hello, world!")); server.enqueue(new MockResponse().setBody("sup, bra?")); server.enqueue(new MockResponse().setBody("yo dog")); server.start(); HttpUrl baseUrl = server.url("/v1/chat/"); // Start the client, connect to baseURL, run some tests. }

Slide 44

Slide 44 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c Testing with OkHttp MockWebServer org.apache.maven.plugins maven-surefire-plugin 2.18.1 -Xbootclasspath/p:alpn-boot-8.1.5.v20150921.jar

Slide 45

Slide 45 text

@fstabr #Devoxx #unrestful https://github.com/fstab/h2c References • Adrian Cole, JavaZone 2015 https://vimeo.com/138955225 • Simone Bordet, Voxxed Days Belgrade 2015 https://www.youtube.com/watch?v=ve3u00pw4V4 • Ilya Grigorik: High Performance Browser Networking, http://hpbn.co