Quarkus: Subatomarer Überschalltierarzt


Dies ist eine kostenlose NacherzÀhlung meines Lightning Talk von der Joker 2019-Konferenz. Seitdem wurden mehrere neue Versionen von Quarkus veröffentlicht, und der Bericht wurde an den aktuellen Stand der Dinge angepasst.


Im Rahmen der Entwicklung unseres CUBA-Plattform- Frameworks achten wir besonders auf die Entwicklungen in der Branche. Obwohl das CUBA-Framework auf Spring basiert, kann man nicht ignorieren, was um Spring herum passiert. Und natĂŒrlich haben alle bemerkt, dass es in letzter Zeit viel LĂ€rm um Cloud-native Frameworks gegeben hat. Zwei Newcomer - Micronaut und Quarkus - betreten ganz zuversichtlich das Gebiet von Spring Boot. Eines Tages wurde beschlossen, ein kleines RnD zu erstellen, dessen Ergebnisse ich ĂŒber die Erfahrung der Arbeit mit dem Framework Quarkus am Beispiel der bekannten Anwendungen - Petclinic - sprechen werde .


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