diff --git a/README.md b/README.md index a0cf979384ecb10741a65ec702e0250e620600fb..05e98b80b025c0cca47a8c7a6c8a935e5f485fa4 100644 --- a/README.md +++ b/README.md @@ -72,3 +72,13 @@ curl -s -D - -H "Accept: application/json" \ http://localhost:9998/myapp/biblio/auteurs/1000 ``` +Filter resources with query parameters : +```shell +curl -v -H "Accept: application/json" \ + "http://127.0.0.1:9998/myapp/biblio/auteurs/filter?nom=Durand&prenom⁼Marie" +``` +Control sort key with header param (default value "nom") : +```shell +curl -v -H "Accept: application/json" -H "sortKey: prenom"\ +"http://127.0.0.1:9998/myapp/biblio/auteurs/filter" +``` \ No newline at end of file diff --git a/pom.xml b/pom.xml index 99e295d738afa2ea9c3b727591deb08d11d79b5c..d9fc501a209e58467ba08053907a389ec92b728f 100644 --- a/pom.xml +++ b/pom.xml @@ -114,8 +114,8 @@ <version>3.8.1</version> <inherited>true</inherited> <configuration> - <source>8</source> - <target>8</target> + <source>15</source> + <target>15</target> </configuration> </plugin> @@ -269,7 +269,7 @@ <version>3.5.4</version> </requireMavenVersion> <requireJavaVersion> - <version>11</version> + <version>15</version> </requireJavaVersion> </rules> </configuration> @@ -319,6 +319,71 @@ <artifactId>maven-site-plugin</artifactId> <version>3.9.1</version> </plugin> + + <!-- Builds a jar that can merge the artifact and its dependencies + https://maven.apache.org/plugins/maven-shade-plugin/ + WARNING minimizeJar can cause trouble, disable it in the child project if needed + + The manifest mainclass can be given with the property ${app.main.class}. + + Its is added to the package phase. + --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-shade-plugin</artifactId> + <version>3.2.3</version> + <configuration> + <createDependencyReducedPom>true</createDependencyReducedPom> + <minimizeJar>false</minimizeJar> + <!-- The shaded artifact is not the main artifact --> + <shadedArtifactAttached>true</shadedArtifactAttached> + <shadedClassifierName>withdependencies</shadedClassifierName> + + <transformers> + <!-- merge services ressource for SPI --> + <transformer + implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" /> + + <!-- makes a default entry point in the shaded jar --> + <transformer + implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> + <manifestEntries> + <Main-Class>${main.class}</Main-Class> + <X-Compile-Source-JDK>${java.version}</X-Compile-Source-JDK> + <X-Compile-Target-JDK>${java.version}</X-Compile-Target-JDK> + </manifestEntries> + </transformer> + + <!-- keep a default config file --> + <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> + <resource>config.properties</resource> + <resource>log4j.properties</resource> + </transformer> + </transformers> + + <!-- removes signatures in uberjar --> + <filters> + <filter> + <artifact>*:*</artifact> + <excludes> + <exclude>META-INF/*.SF</exclude> + <exclude>META-INF/*.DSA</exclude> + <exclude>META-INF/*.RSA</exclude> + </excludes> + </filter> + </filters> + + </configuration> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>shade</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> </build> <properties> diff --git a/src/main/java/fr/univtln/bruno/samples/jaxrs/client/BiblioClient.java b/src/main/java/fr/univtln/bruno/samples/jaxrs/client/BiblioClient.java index 00f1854ad5b058adb5b772401336733e28f12b5a..903059bdaddfabfc2ca7fd4f0f948f178d7366a0 100644 --- a/src/main/java/fr/univtln/bruno/samples/jaxrs/client/BiblioClient.java +++ b/src/main/java/fr/univtln/bruno/samples/jaxrs/client/BiblioClient.java @@ -1,7 +1,6 @@ package fr.univtln.bruno.samples.jaxrs.client; import fr.univtln.bruno.samples.jaxrs.model.BiblioModel.Auteur; -import fr.univtln.bruno.samples.jaxrs.server.BiblioServer; import jakarta.ws.rs.client.Client; import jakarta.ws.rs.client.ClientBuilder; import jakarta.ws.rs.client.Entity; diff --git a/src/main/java/fr/univtln/bruno/samples/jaxrs/exceptions/IllegalArgumentException.java b/src/main/java/fr/univtln/bruno/samples/jaxrs/exceptions/IllegalArgumentException.java index 363591b97dd8057f9a9b96409757e61de097aad5..7a8e69d1bb7286cfb36119731c6b9838e7aabb9e 100644 --- a/src/main/java/fr/univtln/bruno/samples/jaxrs/exceptions/IllegalArgumentException.java +++ b/src/main/java/fr/univtln/bruno/samples/jaxrs/exceptions/IllegalArgumentException.java @@ -1,9 +1,9 @@ package fr.univtln.bruno.samples.jaxrs.exceptions; -import jakarta.ws.rs.core.Response; +import static jakarta.ws.rs.core.Response.*; public class IllegalArgumentException extends BusinessException { public IllegalArgumentException() { - super(Response.Status.NOT_ACCEPTABLE); + super(Status.NOT_ACCEPTABLE); } } diff --git a/src/main/java/fr/univtln/bruno/samples/jaxrs/model/BiblioModel.java b/src/main/java/fr/univtln/bruno/samples/jaxrs/model/BiblioModel.java index e5159c6946907f66e5c864c4f589bd576b8f656e..4859aa67d8275dc68d333aeeb35742ab1d2e2b34 100644 --- a/src/main/java/fr/univtln/bruno/samples/jaxrs/model/BiblioModel.java +++ b/src/main/java/fr/univtln/bruno/samples/jaxrs/model/BiblioModel.java @@ -7,6 +7,7 @@ import jakarta.xml.bind.annotation.XmlAccessorType; import jakarta.xml.bind.annotation.XmlAttribute; import jakarta.xml.bind.annotation.XmlRootElement; import lombok.*; +import lombok.experimental.Delegate; import lombok.experimental.FieldDefaults; import lombok.extern.java.Log; import org.eclipse.collections.api.map.primitive.MutableLongObjectMap; @@ -20,6 +21,8 @@ import java.io.Serializable; @NoArgsConstructor(staticName = "of") public class BiblioModel { private static long lastId = 0; + + @Delegate final MutableLongObjectMap<Auteur> auteurs = LongObjectMaps.mutable.empty(); public Auteur addAuteur(Auteur auteur) throws IllegalArgumentException { diff --git a/src/main/java/fr/univtln/bruno/samples/jaxrs/resources/BiblioResource.java b/src/main/java/fr/univtln/bruno/samples/jaxrs/resources/BiblioResource.java index 2be41d5b16a00158a4cdfaf2797e8890d11e89f6..1ec34be52876397cee81d4af754c3328f887d273 100644 --- a/src/main/java/fr/univtln/bruno/samples/jaxrs/resources/BiblioResource.java +++ b/src/main/java/fr/univtln/bruno/samples/jaxrs/resources/BiblioResource.java @@ -8,9 +8,15 @@ import fr.univtln.bruno.samples.jaxrs.model.BiblioModel.Auteur; import fr.univtln.bruno.samples.jaxrs.status.Status; import jakarta.ws.rs.*; import jakarta.ws.rs.core.MediaType; +import lombok.extern.java.Log; +import java.security.InvalidParameterException; import java.util.Collection; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; +@Log // The Java class will be hosted at the URI path "/biblio" @Path("biblio") @Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_XML}) @@ -28,7 +34,7 @@ public class BiblioResource { @Path("init") public int init() throws IllegalArgumentException { modeleBibliotheque.supprimerAuteurs(); - modeleBibliotheque.addAuteur(Auteur.builder().prenom("Jean").nom("Martin").build()); + modeleBibliotheque.addAuteur(Auteur.builder().prenom("Alfred").nom("Martin").build()); modeleBibliotheque.addAuteur(Auteur.builder().prenom("Marie").nom("Durand").build()); return modeleBibliotheque.getAuteurSize(); } @@ -78,4 +84,26 @@ public class BiblioResource { public Collection<Auteur> getAuteurs() { return modeleBibliotheque.getAuteurs().values(); } + + @GET + @Path("auteurs/filter") + public List<Auteur> getFilteredAuteurs(@QueryParam("nom") String nom, @QueryParam("prenom") String prenom, @QueryParam("biograpĥie") String biographie, + @HeaderParam("sortKey") @DefaultValue("nom") String sortKey) { + log.info("Sort Key: "+sortKey); + //Demo purpose ONLY sorting have to be done in the model + return modeleBibliotheque + .stream() + .filter(auteur -> nom == null || auteur.getNom().equalsIgnoreCase(nom)) + .filter(auteur -> prenom == null || auteur.getPrenom().equalsIgnoreCase(prenom)) + .filter(auteur -> biographie == null || auteur.getBiographie().contains(biographie)) + //We use the news Java 15 switch syntax and value + .sorted(Comparator.comparing(auteur -> switch (sortKey) { + case "nom" -> auteur.getNom(); + case "prenom" -> auteur.getPrenom(); + default -> throw new InvalidParameterException(); + })) + .collect(Collectors.toList()); + } + + } diff --git a/src/main/java/fr/univtln/bruno/samples/jaxrs/status/Status.java b/src/main/java/fr/univtln/bruno/samples/jaxrs/status/Status.java index 1b45ac449ad2e454ea62728b8347fcf7c908ee3d..7a69da2d6c782e0cfdb9156e51414dc34b6f22aa 100644 --- a/src/main/java/fr/univtln/bruno/samples/jaxrs/status/Status.java +++ b/src/main/java/fr/univtln/bruno/samples/jaxrs/status/Status.java @@ -1,7 +1,6 @@ package fr.univtln.bruno.samples.jaxrs.status; import jakarta.ws.rs.NameBinding; -import jakarta.ws.rs.core.Response; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/src/test/java/fr/univtln/bruno/samples/jaxrs/ServerIT.java b/src/test/java/fr/univtln/bruno/samples/jaxrs/ServerIT.java index 97bde0834322e8b470689b88f5585a13658b0080..8d2e71437163720252a382109595ad829f3e0193 100644 --- a/src/test/java/fr/univtln/bruno/samples/jaxrs/ServerIT.java +++ b/src/test/java/fr/univtln/bruno/samples/jaxrs/ServerIT.java @@ -14,6 +14,7 @@ import org.glassfish.jersey.message.internal.MediaTypes; import org.junit.*; import java.util.Collection; +import java.util.List; import static org.junit.Assert.*; @@ -74,7 +75,7 @@ public class ServerIT { public void testGetAuteurJSON() { Auteur responseAuteur = webTarget.path("biblio/auteurs/1").request(MediaType.APPLICATION_JSON).get(Auteur.class); assertNotNull(responseAuteur); - assertEquals("Jean", responseAuteur.getPrenom()); + assertEquals("Alfred", responseAuteur.getPrenom()); assertEquals("Martin", responseAuteur.getNom()); } @@ -85,7 +86,7 @@ public class ServerIT { public void testGetAuteurXML() { Auteur responseAuteur = webTarget.path("biblio/auteurs/1").request(MediaType.TEXT_XML).get(Auteur.class); assertNotNull(responseAuteur); - assertEquals("Jean", responseAuteur.getPrenom()); + assertEquals("Alfred", responseAuteur.getPrenom()); assertEquals("Martin", responseAuteur.getNom()); } @@ -190,4 +191,18 @@ public class ServerIT { .get(String.class); assertTrue(serviceWadl.length() > 0); } + + /** + * Tests filters and query param. + */ + @Test + public void filter() { + List<Auteur> auteurs = webTarget.path("biblio/auteurs/filter") + .queryParam("prenom","Marie") + .request(MediaType.APPLICATION_JSON) + .get(new GenericType<>() {}); + + assertEquals(1, auteurs.size()); + assertEquals("Marie", auteurs.get(0).getPrenom()); + } }