Sending an InputStream to JAX-RS Resource

A JAX-RS resource accepting a plain InputStream:


@Path("uploads")
public class UploadsResource {

    @POST
    @Consumes("*/*")
    public void upload(InputStream stream) throws IOException {
        //consume input stream
        System.out.println("Read: " + stream.read());

    }    
}

...will consume any binary stream (e.g. file upload) of data as:

import java.io.IOException;
import java.io.InputStream;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import org.junit.Before;
import org.junit.Test;

public class UploadsResourceIT {

    private WebTarget tut;

    @Before
    public void init() {
        Client client = ClientBuilder.newClient();
        this.tut = client.target("http://localhost:8080/jaxrs-streaming/resources/uploads");
    }

    @Test
    public void sendStream() {
        InputStream stream = //...

        Response response = this.tut.
                request().
                post(Entity.entity(stream, MediaType.APPLICATION_OCTET_STREAM));
        assertThat(response.getStatus(), is(204));
    }    
}
The System Test is a Java SE client and therefore requires a JAX-RS API implementation (in our example: Apache CXF ):

<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-rs-client</artifactId>
    <version>3.3.1</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-rs-extension-providers</artifactId>
    <version>3.3.1</version>
    <scope>test</scope>
</dependency>  
</dependencies>         

Project created with javaee8-essentials-archetype, the 3kB ThinWAR was built and deployed with: wad.sh in 2329ms

See you at Web, MicroProfile and Java EE Workshops at Munich Airport, Terminal 2 or Virtual Dedicated Workshops / consulting. Is Munich's airport too far? Learn from home: airhacks.io.


Cloudy Jakarta EE and MicroProfile: Microservices, Clouds and Beyond Jakarta EE / MicroProfile airhacks workshops at MUC airport, Winter Edition

airhacks.fm the podcast:

Stay in touch: airhacks.news.

Asynchronous Returns with CompletableFuture with JAX-RS 2.1 / Java EE 8

An expensive method:


public class Messenger {
    public String hello() {
        //heavy lifting
        return "hello!";
    }
}    
...can be directly published asynchronously via a JAX-RS resource:

import java.util.concurrent.CompletableFuture;
import static java.util.concurrent.CompletableFuture.supplyAsync;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;

@Path("messages")
public class MessagesResource {

    @Inject
    Messenger messenger;

    @GET
    public CompletableFuture<String> ping() {
        return supplyAsync(this.messenger::hello);
    }
}    

Project created with javaee8-essentials-archetype, the 4kB ThinWAR was built and deployed with: wad.sh in 2937ms

Big thanks to @OndroMih for the hint during the continuous @czjug hacking.

See you at Web, MicroProfile and Java EE Workshops at Munich Airport, Terminal 2 or Virtual Dedicated Workshops / consulting. Is Munich's airport too far? Learn from home: airhacks.io.


Cloudy Jakarta EE and MicroProfile: Microservices, Clouds and Beyond Jakarta EE / MicroProfile airhacks workshops at MUC airport, Winter Edition

airhacks.fm the podcast:

Stay in touch: airhacks.news.

Quarkus and ThinJARs--airhacks.fm podcast

Subscribe to airhacks.fm podcast via: RSS iTunes

An airhacks.fm conversation with Stuart Douglas (@stuartwdouglas) about:

starting with Visual Basic in high school, with the goal to build games, then quick transition to C++, creating Tetris from scratch in weeks in C++, building first commercial financial planning application with PHP, starting with Java 1.5 and annotations in 2007, Java is popular in Australia, building Seam applications with JBoss 4, contributing to Weld in spare time, improving the performance and startup performance of Weld, working for RedHat as JBoss AS 7 developer, JBoss is more than the application server and the advent of Wildfly, the braning clean up, creating Undertow, WildFly was shipped with deactivated EJB pooling, too small EJB pools can cause performance issues, how to kill EJBs with CDI, EJB vs. CDI, interview with Pavel Samolysov and EJB vs. CDI performance comparison, quarkus is not using reflection for injection, a small team (8 people) started quarkus to leverage GraalVM, the goal of quarkus is to make a subset of Java EE natively compilable to an "unikernel", updating the cloud platform without recompiling the app, serverless with quarkus, serverless without the function disadvantage, 20MB self contained, native images, building Java EE / Jakarta EE unikernels, extremely fast start times for Java EE applications, native images are running with a fraction of RAM, at one point in time, quarkus might be commercially supported by RedHat, CDI portable extensions are not supported now, quarkus wizard is not based on Maven archetype - what is a great idea, Maven is only one of many possible entry points to quarkus, a really good developer experience was always the main goal, hot reload is a must, currently the classloader with the "business" part is just dropped and the app is reloaded, adding dependencies via CLI or pom.xml, quarkus ThinJARs are compatible with the ThinWAR idea, FatJAR's builds have to be slower, packaging all dependencies into a single JAR, using Chrome Dev Tools Protocols for hot reloading the browser, misusing quarkus for building command line tools, community extensions are on the roadmap, quarkus is going to be well integrated with OpenShift, quarkus forum.
Stuart on twitter: (@stuartwdouglas), and github.

See you at Web, MicroProfile and Java EE Workshops at Munich Airport, Terminal 2 or Virtual Dedicated Workshops / consulting. Is Munich's airport too far? Learn from home: airhacks.io.


Cloudy Jakarta EE and MicroProfile: Microservices, Clouds and Beyond Jakarta EE / MicroProfile airhacks workshops at MUC airport, Winter Edition

airhacks.fm the podcast:

Stay in touch: airhacks.news.

Jakarta EE, MicroProfile, OpenLiberty: Better Than Ice Hockey--airhacks.fm podcast

Subscribe to airhacks.fm podcast via: RSS iTunes

An airhacks.fm conversation with Andrew Guibert (@andrew_guibert) about:

old IBM PCs and old school Legos, starting programming in elementary school to write video games, the market for enterprise software is better, than the market for video games, World of Warcraft is good for practicing team work, ice hockey, snowboarding and baseball, getting job at IBM by pitching Nintendo WII hacking, why Java EE is exciting for young developers, OpenLiberty is a dream team at IBM, providing Java EE support for WebSphere Liberty and WebSphere "traditional" customers, Java EE 8 was good, and MicroProfile is a good platform for innovation, quick MicroProfile iterations, sprinkling MicroProfile goodness into existing applications, MicroProfile helps glue things together, OpenLiberty strictly follows the Java EE standards, how OpenLiberty knows what Java EE 8 is, OpenLiberty is built on an OSGi runtime, features are modules with dependencies, OpenLiberty comprises public and internal features, Java EE 8 is a convenience feature which pulls in other modules / features, OpenLIberty also supports users features, OpenLiberty works with EclipseLink, as well as, Hibernate, OpenLiberty comes with generic JPA support with transaction integration, Erin Schnabel fixes OpenLiberty configuration at JavaONE, IBM booth with vi in a few seconds, Erin Schnabel is a 10x-er, IBM MQ / MQS could be the best possible developer experience as JMS provider, Liberty Bikes - a Java EE 8 / MicroProfile Tron-like game, scaling websockets with session affinity, tiny ThinWARs, there is MicroProfile discussion for JWT token production, controlling OpenLiberty from MineCraft, testing JDBC connections, BulkHeads with porcupine, all concurrency in OpenLiberty runs on single, self-tuning ThreadPool
Andy on twitter: @andrew_guibert and github.

See you at Web, MicroProfile and Java EE Workshops at Munich Airport, Terminal 2 or Virtual Dedicated Workshops / consulting. Is Munich's airport too far? Learn from home: airhacks.io.


Cloudy Jakarta EE and MicroProfile: Microservices, Clouds and Beyond Jakarta EE / MicroProfile airhacks workshops at MUC airport, Winter Edition

airhacks.fm the podcast:

Stay in touch: airhacks.news.

Unikernels, Quarkus.io, SPA vs. Websites, JMS, shared deployments, fighting Sonar, Testing--61st airhacks.tv

61st edition of airhacks.tv with the following topics:

"Unikernels, Quarkus.io, SPA vs. Document Oriented Model, Service to Service Communication with JMS, shared deployments, shared entities between microservices, service discovery and WARs, fighting Sonar, Unit-, Integration-, System Tests with or without Arquillian, File Uploads with or without dependencies, Sockets on Java EE"

Any questions left? Ask now: https://gist.github.com/AdamBien/001c1bad3f868a8508783569e192ea3d and get the answers at the next airhacks.tv.

See you at Web, MicroProfile and Java EE Workshops at Munich Airport, Terminal 2 or Virtual Dedicated Workshops / consulting. Is Munich's airport too far? Learn from home: airhacks.io.


Cloudy Jakarta EE and MicroProfile: Microservices, Clouds and Beyond Jakarta EE / MicroProfile airhacks workshops at MUC airport, Winter Edition

airhacks.fm the podcast:

Stay in touch: airhacks.news.

Using MicroProfile Rest Client For System Testing

A JAX-RS resource:


@Path("ping")
public class PingResource {

    @GET
    public String ping() {
        return "Enjoy Java EE 8!";
    }

}    
...can be system tested (checkout: http://javaeetesting.com) with MicroProfile Rest Client by describing the resource with an interface:

import javax.ws.rs.GET;
import javax.ws.rs.Path;
        
@Path("/restclient/resources/ping")
public interface PingClient {

    @GET
    String ping();
}
    
...and creating a proxy implementation with RestClientBuilder:

import java.net.MalformedURLException;
import java.net.URI;
import org.eclipse.microprofile.rest.client.RestClientBuilder;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;


public class RestClientTest {

    @Test
    public void init() throws MalformedURLException {
        URI baseURI = URI.create("http://localhost:8080");
        PingClient client = RestClientBuilder.newBuilder().
                baseUri(baseURI).
                build(PingClient.class);                
        assertNotNull(client);
        String result = client.ping();
        assertNotNull(result);
    }
}

You will need the following dependencies to run the system test from your IDE / CLI:


<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-api</artifactId>
        <version>8.0</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-rs-mp-client</artifactId>
        <version>3.3.1</version>
        <scope>test</scope>
    </dependency>
</dependencies>    

Project created with javaee8-essentials-archetype, the 3kB ThinWAR was built and deployed with: wad.sh in 2940ms

See you at Web, MicroProfile and Java EE Workshops at Munich Airport, Terminal 2 or Virtual Dedicated Workshops / consulting. Is Munich's airport too far? Learn from home: airhacks.io.


Cloudy Jakarta EE and MicroProfile: Microservices, Clouds and Beyond Jakarta EE / MicroProfile airhacks workshops at MUC airport, Winter Edition

airhacks.fm the podcast:

Stay in touch: airhacks.news.

Unikernels, Quarkus.io, SPA vs. Document Oriented Model, Service to Service Communication with JMS--61st airhacks.tv

Agenda for the 61st https://gist.github.com/AdamBien/606e7a0c27ebd6457515741320ff037f airhacks.tv:

  1. quarkus.io and unikernels
  2. SPA vs. Request / Response
  3. Reading TCP sockets with Java EE
  4. Message Brokers and distributed JMS communication
  5. Transactions between Microservices in Java EE
  6. Flyway vs. Liquibase
  7. Multi-lingual content with entities and REST
  8. @Singleton with Bean concurrency with or without locks
  9. Unit Tests, Integration tests, System Tests
  10. How to deal with shared JPA entities between microservices
  11. Coupling vs. cohesion and Boundary Control Entity
See you at Web, MicroProfile and Java EE Workshops at Munich Airport, Terminal 2 or Virtual Dedicated Workshops / consulting. Is Munich's airport too far? Learn from home: airhacks.io.


Cloudy Jakarta EE and MicroProfile: Microservices, Clouds and Beyond Jakarta EE / MicroProfile airhacks workshops at MUC airport, Winter Edition

airhacks.fm the podcast:

Stay in touch: airhacks.news.

Serverless without Functions, OpenShift with a bit Istio--airhacks.fm podcast

Subscribe to airhacks.fm podcast via: RSS or iTunes

An airhacks.fm conversation with Sebastian Daschner (@DaschnerS) about:

being chief Enterprise Service Bus Officer at IBM (not true), Lead Java Advocate for Java at IBM (now true), Sebastian still likes Java EE, the definition of Serverless, there is no need for functions in serverless computing, a reference to episode with Bruno Borges "Jakarta EE / MicroProfile in the Clouds: Runtimes not Servers", the difference between servers and runtimes, focussing on ThinwWARs is serverless, immutable infrastructures with immutable layers, pushing 50 times a day a ThinWAR to the cloud, Payara Configured as example for intermediary layers, Payara s2i, misusing Docker Registry as "FTP", ThinWAR upload triggers a hook and rebuilds a server, ultra productive Java EE, servers do not matter, using FaaS to trigger server re-configuration, functions are too fine grained for the implementation of stock applications, implement the added value of clouds by injecting cloud services, cloud bootstrap / initialization code looks like from 1945, externalizing cloud libraries to immutable images, added value of istio at openshift, cross cutting concerns with Istio, canary releases, routes and observability, istio adds additional configuration overhead, istio adds technical features on top of openshift, a possible killer features of istio, monitoring database traffic with istio, Istio as "feel good factor", some technical dashboards are as usable as lava lamps, monitoring external services, artificially slowing down connections in tests, MQS, hello worlds with Kafka are great, two lines to send a JMS events and one annotation to receive a message, Kafka is great as managed service, the next killer feature of MQS, killer runtimes with microprofile and Java EE, you can find us at jakartaee.blog and this blog is not usable as source for articles

Meet Sebastian at twitter: (@DaschnerS), https://jakartablogs.ee and his blog https://blog.sebastian-daschner.com/.

See you at Web, MicroProfile and Java EE Workshops at Munich Airport, Terminal 2 or Virtual Dedicated Workshops / consulting. Is Munich's airport too far? Learn from home: airhacks.io.


Cloudy Jakarta EE and MicroProfile: Microservices, Clouds and Beyond Jakarta EE / MicroProfile airhacks workshops at MUC airport, Winter Edition

airhacks.fm the podcast:

Stay in touch: airhacks.news.

Monitoring HTTP Requests with MicroProfile Metrics

A Java EE 8 HttpFilter, configured to map all URLs:


import javax.inject.Inject;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.microprofile.metrics.Meter;
import org.eclipse.microprofile.metrics.MetricRegistry;
import org.eclipse.microprofile.metrics.annotation.RegistryType;

@WebFilter(urlPatterns = "/*")
public class FilterEverything extends HttpFilter {

    @Inject
    @RegistryType(type = MetricRegistry.Type.APPLICATION)
    MetricRegistry registry;

    @Override
    protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
        registry.counter(req.getPathInfo()).inc();
        Meter meter = registry.meter("meter_" + req.getPathInfo());
        chain.doFilter(req, res);
        meter.mark();
    }

}

...will generate for the invocation of the PingResource:


@Path("ping")
public class PingResource {

    @GET
    @Path("slow")
    public String slow() {
        //heavy lifting
        return "42";
    }

    @GET
    @Path("fast")
    public String fast() {
        return "21";
    }

}

...the following prometheus metrics (curl http://localhost:8080/metrics/application):


# TYPE application:/ping/slow counter
application:/ping/slow 1
# TYPE application:/ping/fast counter
application:/ping/fast 1
# TYPE application:meter_/ping/fast_total counter
application:meter_/ping/fast_total 1
# TYPE application:meter_/ping/fast_rate_per_second gauge
application:meter_/ping/fast_rate_per_second 0.044544529211015586
# TYPE application:meter_/ping/fast_one_min_rate_per_second gauge
application:meter_/ping/fast_one_min_rate_per_second 0.155760156614281
# TYPE application:meter_/ping/fast_five_min_rate_per_second gauge
application:meter_/ping/fast_five_min_rate_per_second 0.1902458849001428
# TYPE application:meter_/ping/fast_fifteen_min_rate_per_second gauge
application:meter_/ping/fast_fifteen_min_rate_per_second 0.1966942907643235
# TYPE application:meter_/ping/slow_total counter
application:meter_/ping/slow_total 1
# TYPE application:meter_/ping/slow_rate_per_second gauge
application:meter_/ping/slow_rate_per_second 0.05214608959864638
# TYPE application:meter_/ping/slow_one_min_rate_per_second gauge
application:meter_/ping/slow_one_min_rate_per_second 0.16929634497812282
# TYPE application:meter_/ping/slow_five_min_rate_per_second gauge
application:meter_/ping/slow_five_min_rate_per_second 0.1934432200964012
# TYPE application:meter_/ping/slow_fifteen_min_rate_per_second gauge
application:meter_/ping/slow_fifteen_min_rate_per_second 0.19779007785878447

...also available as JSON (curl -H"Accept: application/json" http://localhost:8080/metrics/application):

{
    "/ping/slow": 1,
    "/ping/fast": 1,
    "meter_/ping/fast": {
        "count": 1,
        "fiveMinRate": 0.14571471450227858,
        "oneMinRate": 0.04105793151598188,
        "fifteenMinRate": 0.17996489624183667,
        "meanRate": 0.009531711523994577
    },
    "meter_/ping/slow": {
        "count": 1,
        "fiveMinRate": 0.14571471450227858,
        "oneMinRate": 0.04105793151598188,
        "fifteenMinRate": 0.17996489624183667,
        "meanRate": 0.009838528938613995
    }
}

Project was created with javaee8-essentials-archetype, the 5kB ThinWAR was built and deployed with wad.sh in 2963ms and tested with Payara 5.

See you at Web, MicroProfile and Java EE Workshops at Munich Airport, Terminal 2 or Virtual Dedicated Workshops / consulting. Is Munich's airport too far? Learn from home: airhacks.io.


Cloudy Jakarta EE and MicroProfile: Microservices, Clouds and Beyond Jakarta EE / MicroProfile airhacks workshops at MUC airport, Winter Edition

airhacks.fm the podcast:

Stay in touch: airhacks.news.

Optimizing for Humans, Not Machines--airhacks.fm podcast

Subscribe to airhacks.fm podcast via: RSS iTunes

An airhacks.fm conversation with Simon Harrer (@simonharrer) about:
Amstrad Laptop, first line of VB code was a commercial one, customers two desks away, Scheme is an excellent language to learn programming, Java is great - mainly because of the tool support, Eclipse was the first opensource IDE with decent refactoring support, Bamberg is the home of Schlenkerla, teaching is the best way to learn, therefore teaching is selfish, building portals for students with PHP and Joomla, building e-commerce shops for students with Ruby on Rails, 2006 everything had to be Rails, PhD about choreography and distributed transactions, too high expectations on workflow and rule engines, workflow engines are for developers and not for business people, central process view is still desirable, startups with Bosch, in Germany it is hard to find developers who are willing to join startups, Simon works for InnoQ and Stefan Tilkov, Computer Science University of Bamberg, the pragmatic book: Java by Comparison by The Pragmatic Bookshelf, in streams there are no exceptions, over-abstractions cause trouble, reviewing the code of thousands of students for six years, it is unusual for universities to promote pragmatic code, be strict about adding external libraries, clear separation between infrastructure and business logic helps with clean code, moving domain specific libraries into the infrastructure, human centered code, optimizing for machines, not for humans is problematic, writing bad code is often not intentional, "Abstract, If, Impl, Default, Bean Conventions - Just For Lazy Developers", don't write for reuse, reuse rarely happens, reuse as motivator for bad abstractions, do repeat yourself, than refactor, "How To Comment With JavaDoc", Book: Java by Comparison, Become a Java Craftsman in 70 Examples.
Simon Harrer on twitter: (@simonharrer).

See you at Web, MicroProfile and Java EE Workshops at Munich Airport, Terminal 2 or Virtual Dedicated Workshops / consulting. Is Munich's airport too far? Learn from home: airhacks.io.


Cloudy Jakarta EE and MicroProfile: Microservices, Clouds and Beyond Jakarta EE / MicroProfile airhacks workshops at MUC airport, Winter Edition

airhacks.fm the podcast:

Stay in touch: airhacks.news.

Online Workshops
realworldpatterns.com
...the last 150 posts
...the last 10 comments
License