Quarkus: Vétérinaire subatomique supersonique


Il s'agit d'une nouvelle version gratuite de mon Lightning Talk de la conférence Joker 2019. Depuis lors, plusieurs nouvelles versions de Quarkus ont été publiées, le rapport a été aligné sur l'état actuel des choses.


Dans le cadre du développement de notre plateforme CUBA Platform , nous accordons une grande attention à ce qui se passe dans l'industrie. Bien que le cadre CUBA soit construit autour de Spring, on ne peut ignorer ce qui se passe autour. Et, bien sûr, tout le monde a remarqué que ces derniers temps, il y a eu beaucoup de bruit autour des frameworks natifs du cloud . Deux nouveaux venus - Micronaut et Quarkus commencent avec confiance à pénétrer sur le territoire de Spring Boot. Un jour, il a été décidé de faire un petit RnD, dont les résultats dont je parlerai de l'expérience de travail avec le framework Quarkus l'exemple des applications bien connues - Petclinic .


Quarkus?


Quarkus . : , , RedHat (Hibernate ORM, Eclipse Vert.x, Netty, RESTEasy) , Java API. Quarkus Eclipse Microprofile 3.2. , , , , AOT GraalVM.
Quarkus - UI — Qute. RnD (, , , ), React.


?


Petclinic – -, Spring Framework. Spring, , : Spring, Spring Boot, Kotlin, GraphQL API, , . — , . "" , : REST API Quarkus, , ReactJS.


Front-end , , Spring. ? API REST . , dependency injection. Spring , JVM. Quarkus?


. Quarkus "" JVM , , Spring. Graal VM Native Image, , , (Closed World Assumption), , . GraalVM .


Quarkus AOT. – build augmentation. Quarkus , . — Petclinic : Hibernate, RESTEasy, ArC dependency injection.


, Quarkus , – .


        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-hibernate-orm-panache</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-junit5</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.5</version>
            <scope>test</scope>
        </dependency>

!



, Hibernate. petclinic Spring, Hibernate ORM. , RedHat Hibernate, ORM Quarkus.


Quarkus .


EntityManager :


public class ClinicService {

    @Inject
    EntityManager em;

    public List<PetType> findAllPetTypes() {
        return em.createNamedQuery("PetTypes.findAll", PetType.class).getResultList();
    }

    public PetType findPetTypeById(Integer petTypeId) {
        return em.find(PetType.class, petTypeId);
    }
// ..
}

Panache. PanacheEntity ( BaseEntity), (find, list, delete, persist ..). , Panache:


public class ClinicService {

    public List<PetType> findAllPetTypes() {
        return PetType.listAll();
    }

    public PetType findPetTypeById(Long petTypeId) {
        return PetType.findById(petTypeId);
    }
// ..
}

, Panache , , .


, , Panache .



@ApplicationScoped, ClinicService. @Transactional. . , . , , .


@ApplicationScoped
@Transactional
public class ClinicService {

    public List<PetType> findAllPetTypes() {
        return PetType.listAll();
    }

    public Collection<Vet> findAllVets() {
        return Vet.findAll(Sort.ascending("firstName")).list();
    }

    public Pet updatePet(long petId, Pet pet) {
        Pet currentPet = findPetById(petId);
        if (currentPet == null) {
            return null;
        }
        currentPet.setBirthDate(pet.getBirthDate());
        currentPet.setName(pet.getName());
        currentPet.setType(pet.getType());
        return currentPet;
    }
// ..
}

CDI Quarkus . , @ConversationScoped, , , Quarkus . — . @Inject , @Singleton — , @RequestScoped @SessionScoped — . — CDI, . — .



REST API JAX-RS, Spring. Spring , JAX-RS, , – , REST .
- . Quarkus- .


@Path("/api")
@Produces(MediaTypes.APPLICATION_JSON_UTF8)
@Consumes(MediaTypes.APPLICATION_JSON_UTF8)
public class OwnersResource {

    @Inject
    ClinicService clinicService;

    @POST
    @Path("/owner")
    public Response addOwner(@Valid Owner owner) {
        owner = clinicService.saveOwner(owner);
        URI uri = URI.create(String.format("/api/owner/%s", owner.getId()));
        return Response.ok(owner).location(uri).build();
    }

    @GET
    @Path("/owner/{ownerId}")
    public Response getOwner(@PathParam("ownerId") long ownerId) {
        Owner owner = clinicService.findOwnerById(ownerId);
        if (owner == null) {
            return Response.status(Response.Status.NOT_FOUND).build();
        }
        return Response.ok(owner).build();
    }
// ..
}

?


RESTAssured JUnit, , . .


@QuarkusTest
public class PetTypesResourceTest {

    @Test
    public void testListAllPetTypes() {
        given()
                .when()
                .get("api/pettypes")
                .then()
                .statusCode(200)
                .body(
                        containsString("cat"),
                        containsString("dog"),
                        containsString("lizard"),
                        containsString("snake"),
                        containsString("bird"),
                        containsString("hamster")
                );
    }
// ..

!


, – . – - Aplication.java Quarkus , .


development mode, :


./mvnw quarkus:dev

Uber Jar, quarkus.package.uber-jar=true application.properties,


./mvnw package

-runner target. quarkus-petclinic-rest-1.0-SNAPSHOT-runner.jar. maven, Quarkus Gradle .


, Docker , , .


?


Petclinic Quarkus , 2 , UberJar «» Petclinic, Spring Boot. H2, in-memory. Hibernate . .


Spring Boot Uber Jar:


17:39:13 INFO 26780 --- [main] o.s.s.petclinic.PetClinicApplication     : Started PetClinicApplication in 14.09 seconds (JVM running for 14.917)

Quarkus Uber Jar:


17:37:26 INFO [io.quarkus]] (main) quarkus-petclinic-rest 1.0-SNAPSHOT (running on Quarkus 1.2.1.Final) started in 6.377s. Listening on: http://0.0.0.0:8080

— , : AOT GraalVM Native Image. , Micronaut , Spring. Quarkus – , maven.


./mvnw package -Pnative.

— !


15:53:18 INFO [io.quarkus]] (main) quarkus-petclinic-rest 1.0-SNAPSHOT (running on Quarkus 1.2.1.Final) started in 0.045s. Listening on: http://0.0.0.0:8080

Linux pmap, Quarkus. RSS – resident set size, .
Spring Boot Uber Jar:


7910:   java -jar spring-petclinic-2.1.0.BUILD-SNAPSHOT.jar
Address           Kbytes     RSS   Dirty Mode  Mapping
0000000000400000       4       4       0 r-x-- java
...
ffffffffff600000       4       0       0 r-x--   [ anon ]
---------------- ------- -------- ------- 
total kB         5071540  971,740  934364

Quarkus Uber Jar:


7795:   java -jar quarkus-petclinic-rest-1.0-SNAPSHOT-runner.jar
Address           Kbytes     RSS   Dirty Mode  Mapping
0000000000400000       4       4       0 r-x-- java
...
ffffffffff600000       4       0       0 r-x--   [ anon ]
---------------- ------- -------- ------- 
total kB         5006732  523,648  483288

– , GraalVM. 20 Spring Boot .


3737:   ./quarkus-petclinic-rest-1.0-SNAPSHOT-runner
Address           Kbytes     RSS   Dirty Mode  Mapping
0000000000400000      12      12       0 r---- quarkus-petclinic-runner
...
ffffffffff600000       4       0       0 r-x--   [ anon ]
---------------- ------- -------- ------- 
total kB          675500   50,272  11668


. Quarkus , , dev mode. - , . IDEA , , . remote port.


Developer Mode – . . Quarkus , . " — — — ". , , , Quarkus , . — debug , .



, API, Elytron, . , Quarkus . extension, : .
users.properties. — , — . plain text, , .


admin=admin
vet=vet

roles.properties. — , — .


admin=ROLE_OWNER_ADMIN, ROLE_VET_ADMIN, ROLE_ADMIN
vet=ROLE_VET_ADMIN

, .


public class Roles {
    public static final String OWNER_ADMIN = "ROLE_OWNER_ADMIN";
    public static final String VET_ADMIN = "ROLE_VET_ADMIN";
    public static final String ADMIN = "ROLE_ADMIN";
}

, . , .


public class VetsResource {

    @GET
    @Path("/vets")
    @RolesAllowed(Roles.VET_ADMIN)
    public Response getAllSpecialties() {
    //    
    }
}

React API , . ACCEPTED base64 API.


@Path("api/auth")
@PermitAll
@Produces(MediaTypes.APPLICATION_JSON_UTF8)
@Consumes(MediaTypes.APPLICATION_JSON_UTF8)
public class AuthResource {

    @POST
    public Response authorize(@Context SecurityContext sc) {
        Principal userPrincipal = sc.getUserPrincipal();
        if (userPrincipal != null) {
            return Response.status(Response.Status.ACCEPTED).entity(userPrincipal).build();
        } else {
            return Response.status(Response.Status.UNAUTHORIZED).build();
        }
    }
}

Quarkus. CORS Security . - CORS . , . , CORS , React . - React .


Spring


Quarkus , Spring API. , . , Inject Autowired. API , , , , . , , , Spring. .


JPA , Spring.


@Repository
public interface OwnerRepository extends CrudRepository<Owner, Integer> {
    Collection<Owner> findOwnersByLastNameIsLike(String lastNameString);
}

, , . , .


Quarkus .


@Service
@Transactional
public class ClinicService {

    @Autowired
    OwnerRepository ownerRepository;

    public Collection<Owner> findOwnerByLastName(String ownerLastName) {
        return ownerRepository.findOwnersByLastNameIsLike(ownerLastName+"%");
    }
//…
}

.


@RestController
@RequestMapping(path = "/api", 
        consumes = MediaTypes.APPLICATION_JSON_UTF8, 
        produces = MediaTypes.APPLICATION_JSON_UTF8)
public class OwnersResource {

    @Autowired
    ClinicService clinicService;

    @GetMapping("/owner/{ownerId}")
    @RolesAllowed({Roles.OWNER_ADMIN, Roles.VET_ADMIN})
    public ResponseEntity<Owner> getOwner(@PathVariable("ownerId") int ownerId) {
        Owner owner = null;
        owner = clinicService.findOwnerById(ownerId);
        if (owner == null) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
        }
        return ResponseEntity.ok(owner);
    }
//...
}

, Quarkus Spring. , , . RedHat , Java .



Quarkus , RedHat , . , . Quarkus — Lufthansa.


: RedHat Quarkus , Spring . Quarkus , .


, backend – Quarkus. , AOT – .


, Quarkus, Spring - ( , - Spring). , , Spring Quarkus .


, , Spring Boot CUBA Platform.


– GitHub. .

Source: https://habr.com/ru/post/undefined/


All Articles