diff --git a/README.md b/README.md index f4d8f741e3b6cfc25321e2c4978d196e9b17673e..1580d8ea7c790e078c2a756cd9e88f86ae28f7b0 100644 --- a/README.md +++ b/README.md @@ -12,23 +12,30 @@ Vous proposerez un mécanisme d'authentification adéquat tenant compte des diff ## Instructions de build et d'exécution AVEC la vidéo -La vidéo `video.mp4` montre pas à pas comment utiliser ce projet (voir la [section suivante pour avoir les détails des commandes](#instructions-de-build-et-dexécution-sans-la-vidéo)) +La vidéo `video.mp4` montre pas à pas comment utiliser ce projet + +### Description de la vidéo + +On commence par compiler puis démarrer le programme `FlopBox`, puis on démarre 2 serveurs FTP sur les ports `2121` et `2122` et l'utilisateur `user/password` + +En haut à droite se trouve le dossier du serveur1 `dossier_serveur_ftp1` et en dessous le dossier du serveur2 `dossier_serveur_ftp2`, qui sont vides au départ ## Instructions de build et d'exécution SANS la vidéo ### Build l'archive Pour créer l'archive `FlopBox.jar`, il faut avoir Java 17 et Maven d'installés, et exécuter la commande suivante à la racine du projet : - ```shell mvn clean package ``` ### Utiliser le programme +Lancer le programme FlopBox : ```shell java -jar target/FlopBox.jar ``` +Lancer 2 serveurs FTP pour pouvoir tester ; le serveur1 utilise le dossier `dossier_serveur_ftp1` et le SERVEUR2 utilise le dossier `dossier_serveur_ftp2` : ```shell pip install --user pyftpdlib python3 serveur_ftp.py serveur1 @@ -39,8 +46,6 @@ Identifiants : - mode anonyme : anonymous/anonymous - utilisateur : user/password -ou ftp.ubuntu.com - ### Exécuter les tests Pour exécuter uniquement les tests il faut lancer la commande suivante : @@ -49,14 +54,6 @@ Pour exécuter uniquement les tests il faut lancer la commande suivante : mvn test ``` -```shell -curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer valid-token-1" -d '{"alias":"mon-ftp","host":"localhost","port":2121}' http://localhost:8080/ftps - -curl -H "Authorization: Bearer valid-token-1" http://localhost:8080/ftps - -curl -H "Authorization: Bearer valid-token-1" -o fichier.html http://localhost:8080/ftps/mon-ftp/test/download -``` - ## Détails du code ### Générer la javadoc Lancer la commande suivante : @@ -180,3 +177,9 @@ curl -X DELETE -H "Authorization: Bearer valid-token-1" -H "X-FTP-User: user" -H ```shell curl -X GET -H "Authorization: Bearer valid-token-1" -H "X-FTP-User: user" -H "X-FTP-Pass: password" http://localhost:8080/ftps/search/fichier1 ``` + +## L'API + +Les routes sont visibles dans le fichier `src/main/java/fil/sr2/flopbox/FTPResource.java` + + diff --git a/assets/swagger.png b/assets/swagger.png new file mode 100644 index 0000000000000000000000000000000000000000..ae5966fefe6feef9d30610fafe72b435f0cfc19b Binary files /dev/null and b/assets/swagger.png differ diff --git a/pom.xml b/pom.xml index 802954471a4931c42cef2e2d88a24415a4a8037f..d33966b4f649cc4a7abac52be75361ade4c00870 100644 --- a/pom.xml +++ b/pom.xml @@ -53,6 +53,25 @@ <artifactId>commons-net</artifactId> <version>3.8.0</version> </dependency> + <!-- Test --> + <dependency> + <groupId>org.apache.ftpserver</groupId> + <artifactId>ftpserver-core</artifactId> + <version>1.2.0</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <version>3.12.4</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>commons-io</groupId> + <artifactId>commons-io</artifactId> + <version>2.11.0</version> + <scope>test</scope> + </dependency> </dependencies> <build> diff --git a/src/main/java/fil/sr2/flopbox/FTPResource.java b/src/main/java/fil/sr2/flopbox/FTPResource.java index 2d857c3a006c0d08f61f1818cea5b1c44d208afe..b42c60db66df11e8cb709ee837a24b069ceefd12 100644 --- a/src/main/java/fil/sr2/flopbox/FTPResource.java +++ b/src/main/java/fil/sr2/flopbox/FTPResource.java @@ -12,6 +12,7 @@ import java.util.ArrayList; import fil.sr2.flopbox.utils.*; +/** The class with the paths */ @Path("/ftps") public class FTPResource { @@ -80,15 +81,6 @@ public class FTPResource { return Response.ok(results).build(); } - @DELETE - @Path("/{alias}") - public Response removeFTPServer(@PathParam("alias") String alias) { - System.out.println("removeFTPServer()"); - boolean removed = FTPServerRepository.getInstance().removeServer(alias); - return removed ? Response.noContent().build() - : Response.status(Response.Status.NOT_FOUND).build(); - } - @PUT @Path("/{alias}") @Consumes(MediaType.APPLICATION_JSON) @@ -99,6 +91,15 @@ public class FTPResource { : Response.status(Response.Status.NOT_FOUND).build(); } + @DELETE + @Path("/{alias}") + public Response removeFTPServer(@PathParam("alias") String alias) { + System.out.println("removeFTPServer()"); + boolean removed = FTPServerRepository.getInstance().removeServer(alias); + return removed ? Response.noContent().build() + : Response.status(Response.Status.NOT_FOUND).build(); + } + // --- Endpoints pour les opérations FTP --- @GET @@ -142,7 +143,6 @@ public class FTPResource { } // GET pour télécharger une ressource : fichier ou dossier compressé en ZIP - @GET @Path("/{alias}/{path: .+}") public Response getFTPResource( @@ -198,20 +198,18 @@ public class FTPResource { } } - @POST - @Path("/{alias}/upload-dir/{path: .*}") - @Consumes(MediaType.APPLICATION_OCTET_STREAM) - public Response uploadDirectory( + // DELETE pour supprimer une ressource (fichier ou dossier récursivement) + @DELETE + @Path("/{alias}/{path: .+}") + public Response deleteResource( @PathParam("alias") String alias, @PathParam("path") String path, @HeaderParam("X-FTP-User") String user, - @HeaderParam("X-FTP-Pass") String pass, - InputStream zipStream) { - - System.out.println("uploadDirectory()"); + @HeaderParam("X-FTP-Pass") String pass) { + System.out.println("deleteResource()"); try { - ftpService.uploadDirectoryAsZip(alias, path, user, pass, zipStream); - return Response.ok().build(); + ftpService.deleteResource(alias, path, user, pass); + return Response.noContent().build(); } catch (FTPException e) { return Response.status(e.getStatus()).entity(e.getMessage()).build(); } catch (IOException e) { @@ -241,18 +239,20 @@ public class FTPResource { } } - // DELETE pour supprimer une ressource (fichier ou dossier récursivement) - @DELETE - @Path("/{alias}/{path: .+}") - public Response deleteResource( + @POST + @Path("/{alias}/upload-dir/{path: .*}") + @Consumes(MediaType.APPLICATION_OCTET_STREAM) + public Response uploadDirectory( @PathParam("alias") String alias, @PathParam("path") String path, @HeaderParam("X-FTP-User") String user, - @HeaderParam("X-FTP-Pass") String pass) { - System.out.println("deleteResource()"); + @HeaderParam("X-FTP-Pass") String pass, + InputStream zipStream) { + + System.out.println("uploadDirectory()"); try { - ftpService.deleteResource(alias, path, user, pass); - return Response.noContent().build(); + ftpService.uploadDirectoryAsZip(alias, path, user, pass, zipStream); + return Response.ok().build(); } catch (FTPException e) { return Response.status(e.getStatus()).entity(e.getMessage()).build(); } catch (IOException e) { diff --git a/src/main/java/fil/sr2/flopbox/FTPServerRepository.java b/src/main/java/fil/sr2/flopbox/FTPServerRepository.java index 73cd3b8351b9675902d6337c062834c4761e5d7d..2bec8ddd67811464274b3e299ca190f6c26a77c6 100644 --- a/src/main/java/fil/sr2/flopbox/FTPServerRepository.java +++ b/src/main/java/fil/sr2/flopbox/FTPServerRepository.java @@ -4,6 +4,7 @@ import java.util.*; import fil.sr2.flopbox.utils.*; +/** Take care of the FTP servers and their aliases */ public class FTPServerRepository { private static FTPServerRepository instance = new FTPServerRepository(); private Map<String, FTPServerConfig> serverMap = new HashMap<>(); diff --git a/src/main/java/fil/sr2/flopbox/FTPService.java b/src/main/java/fil/sr2/flopbox/FTPService.java index 82e6cf0c9a4994b548b1ef7495b9f2848c7fc372..535933cdbf8ef375f7e63df64f7bc90e83e0684f 100644 --- a/src/main/java/fil/sr2/flopbox/FTPService.java +++ b/src/main/java/fil/sr2/flopbox/FTPService.java @@ -17,6 +17,7 @@ import java.io.ByteArrayInputStream; import fil.sr2.flopbox.utils.*; +/** Class with methods used in FTPResource */ public class FTPService { public FtpNode getResourceTree(String alias, String path, String user, String pass) @@ -389,9 +390,7 @@ public class FTPService { String newPath = currentPath.isEmpty() ? node.name : currentPath + "/" + node.name; // Si le nom contient le terme recherché (fichier ou dossier) if (node.name.toLowerCase().contains(searchTerm.toLowerCase())) { - // Construction de l’URL FTP. On suppose que FTPServerConfig possède une méthode - // getHost(). - String ftpUrl = "ftp://" + config.getHost() + "/" + newPath; + String ftpUrl = "http://" + config.getHost() + "/" + newPath; urls.add(ftpUrl); } // Parcours des enfants si le nœud est un répertoire diff --git a/src/main/java/fil/sr2/flopbox/MyResource.java b/src/main/java/fil/sr2/flopbox/MyResource.java deleted file mode 100644 index 994c3193b01070cb0375ffefe52edd5abb8af2be..0000000000000000000000000000000000000000 --- a/src/main/java/fil/sr2/flopbox/MyResource.java +++ /dev/null @@ -1,25 +0,0 @@ -package fil.sr2.flopbox; - -import jakarta.ws.rs.GET; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.core.MediaType; - -/** - * Root resource (exposed at "myresource" path) - */ -@Path("myresource") -public class MyResource { - - /** - * Method handling HTTP GET requests. The returned object will be sent - * to the client as "text/plain" media type. - * - * @return String that will be returned as a text/plain response. - */ - @GET - @Produces(MediaType.TEXT_PLAIN) - public String getIt() { - return "Got it!"; - } -} diff --git a/src/main/java/fil/sr2/flopbox/utils/AuthFilter.java b/src/main/java/fil/sr2/flopbox/utils/AuthFilter.java index 2d28ee5b1bc317528d6cbe6e8da69f9a8d5c5781..d4002ca7bf810f786eddb4547765b6a921155d9d 100644 --- a/src/main/java/fil/sr2/flopbox/utils/AuthFilter.java +++ b/src/main/java/fil/sr2/flopbox/utils/AuthFilter.java @@ -10,6 +10,7 @@ import jakarta.ws.rs.core.*; import jakarta.ws.rs.container.*; import jakarta.ws.rs.ext.Provider; +/** Handles user authentication to the Flopbox proxy */ @Provider @Priority(Priorities.AUTHENTICATION) public class AuthFilter implements ContainerRequestFilter { diff --git a/src/main/java/fil/sr2/flopbox/utils/FTPException.java b/src/main/java/fil/sr2/flopbox/utils/FTPException.java index de05f079e78d31c6a3d563dd3574550d28d0b7bb..7ad4df04188a830a59c6d1eeff042a2562b9ccee 100644 --- a/src/main/java/fil/sr2/flopbox/utils/FTPException.java +++ b/src/main/java/fil/sr2/flopbox/utils/FTPException.java @@ -1,5 +1,6 @@ package fil.sr2.flopbox.utils; +/** An exception for FTP problems */ public class FTPException extends Exception { private final int status; diff --git a/src/main/java/fil/sr2/flopbox/utils/FTPServerConfig.java b/src/main/java/fil/sr2/flopbox/utils/FTPServerConfig.java index 7e95f471d0387b052cdb3c2bdab2ea05e07b37b1..ebd5bb8b7de628b0dc85071486366b9c09a8689c 100644 --- a/src/main/java/fil/sr2/flopbox/utils/FTPServerConfig.java +++ b/src/main/java/fil/sr2/flopbox/utils/FTPServerConfig.java @@ -1,5 +1,6 @@ package fil.sr2.flopbox.utils; +/** Represents the configuration of a FTP server */ public class FTPServerConfig { private String alias; private String host; diff --git a/src/test/java/fil/sr2/flopbox/EmbeddedFTPServer.java b/src/test/java/fil/sr2/flopbox/EmbeddedFTPServer.java new file mode 100644 index 0000000000000000000000000000000000000000..b9ef916cd875c0b39db461174141a5dc67270a34 --- /dev/null +++ b/src/test/java/fil/sr2/flopbox/EmbeddedFTPServer.java @@ -0,0 +1,49 @@ +package fil.sr2.flopbox; + +import org.apache.ftpserver.FtpServer; +import org.apache.ftpserver.FtpServerFactory; +import org.apache.ftpserver.ftplet.FtpException; +import org.apache.ftpserver.listener.ListenerFactory; +import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory; +import org.apache.ftpserver.usermanager.impl.BaseUser; +import java.io.File; + +public class EmbeddedFTPServer { + private FtpServerFactory serverFactory; + private FtpServer server; + private PropertiesUserManagerFactory userManagerFactory; + private int port; + + public EmbeddedFTPServer(int port) { + this.port = port; + serverFactory = new FtpServerFactory(); + ListenerFactory listenerFactory = new ListenerFactory(); + listenerFactory.setPort(port); + serverFactory.addListener("default", listenerFactory.createListener()); + userManagerFactory = new PropertiesUserManagerFactory(); + serverFactory.setUserManager(userManagerFactory.createUserManager()); + } + + public void start() throws FtpException { + server = serverFactory.createServer(); + server.start(); + } + + public void stop() { + if (server != null) { + server.stop(); + } + } + + public void addUser(String username, String password, File homeDir) throws FtpException { + BaseUser user = new BaseUser(); + user.setName(username); + user.setPassword(password); + user.setHomeDirectory(homeDir.getAbsolutePath()); + serverFactory.getUserManager().save(user); + } + + public int getPort() { + return port; + } +} diff --git a/src/test/java/fil/sr2/flopbox/FTPResourceTest.java b/src/test/java/fil/sr2/flopbox/FTPResourceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..b22ce300a8098a608517b12fb27b275c3f8cf23b --- /dev/null +++ b/src/test/java/fil/sr2/flopbox/FTPResourceTest.java @@ -0,0 +1,315 @@ +package fil.sr2.flopbox; + +import fil.sr2.flopbox.utils.FTPException; +import org.apache.commons.io.FileUtils; +import org.junit.*; +import org.mockito.Mockito; + +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.UriBuilder; +import jakarta.ws.rs.core.UriInfo; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.List; +import java.util.Map; +import java.util.HashMap; +import java.lang.reflect.Method; + +import static org.junit.Assert.*; + +import fil.sr2.flopbox.*; +import fil.sr2.flopbox.utils.*; + +public class FTPResourceTest { + private static EmbeddedFTPServer embeddedFTPServer; + private static File ftpHomeDir; + private static final String USER = "testuser"; + private static final String PASS = "testpass"; + private static final String ALIAS = "testserver"; + private static int ftpPort; + + @BeforeClass + public static void setUpClass() throws Exception { + ftpHomeDir = Files.createTempDirectory("ftp-test").toFile(); + ftpPort = 2123; + embeddedFTPServer = new EmbeddedFTPServer(ftpPort); + embeddedFTPServer.addUser(USER, PASS, ftpHomeDir); + embeddedFTPServer.start(); + } + + @AfterClass + public static void tearDownClass() throws Exception { + embeddedFTPServer.stop(); + FileUtils.deleteDirectory(ftpHomeDir); + } + + @Before + public void setUp() throws IOException { + // Reset repository and add test server + FTPServerRepository repo = FTPServerRepository.getInstance(); + repo.getAllServers().forEach(s -> repo.removeServer(s.getAlias())); + FTPServerConfig config = new FTPServerConfig(ALIAS, "localhost", ftpPort); + repo.addServer(config); + + // Create a test file in FTP home + File testFile = new File(ftpHomeDir, "testfile.txt"); + FileUtils.writeStringToFile(testFile, "test content", StandardCharsets.UTF_8); + } + + @After + public void tearDown() throws IOException { + // Clean FTP home directory + FileUtils.cleanDirectory(ftpHomeDir); + } + + @Test + public void testListFTPServers() { + FTPResource resource = new FTPResource(); + Response response = resource.listFTPServers(); + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + List<FTPServerConfig> servers = (List<FTPServerConfig>) response.getEntity(); + assertTrue(servers.stream().anyMatch(s -> ALIAS.equals(s.getAlias()))); + } + + @Test + public void testAddFTPServerDuplicate() { + FTPResource resource = new FTPResource(); + UriInfo uriInfo = Mockito.mock(UriInfo.class); + Mockito.when(uriInfo.getAbsolutePathBuilder()).thenReturn(new UriBuilderMock()); + + FTPServerConfig config = new FTPServerConfig(ALIAS, "localhost", 21); + Response response = resource.addFTPServer(config, uriInfo); + assertEquals(Response.Status.CONFLICT.getStatusCode(), response.getStatus()); + } + + @Test + public void testRemoveFTPServerSuccess() { + FTPResource resource = new FTPResource(); + Response response = resource.removeFTPServer(ALIAS); + assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus()); + assertNull(FTPServerRepository.getInstance().getServer(ALIAS)); + } + + @Test + public void testUpdateFTPServerSuccess() { + FTPResource resource = new FTPResource(); + FTPServerConfig newConfig = new FTPServerConfig(ALIAS, "localhost", 2122); + Response response = resource.updateFTPServer(ALIAS, newConfig); + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + assertEquals(2122, FTPServerRepository.getInstance().getServer(ALIAS).getPort()); + } + + @Test + public void testGetFTPRoot() { + FTPResource resource = new FTPResource(); + Response response = resource.getFTPRoot(ALIAS, USER, PASS); + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + FTPService.FtpNode root = (FTPService.FtpNode) response.getEntity(); + assertTrue(root.children.stream().anyMatch(node -> "testfile.txt".equals(node.name))); + } + + @Test + public void testGetFTPResourceFile() { + FTPResource resource = new FTPResource(); + Response response = resource.getFTPResource(ALIAS, "testfile.txt", USER, PASS); + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + assertEquals("text/plain", response.getHeaderString("Content-Type")); + assertTrue(((byte[]) response.getEntity()).length > 0); + } + + @Test + public void testSearchFiles() { + FTPResource resource = new FTPResource(); + Response response = resource.searchFiles("testfile.txt", USER, PASS); + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + Map<String, List<String>> results = (Map<String, List<String>>) response.getEntity(); + assertFalse(results.isEmpty()); + } + + @Test + public void testInvalidCredentials() { + FTPResource resource = new FTPResource(); + Response response = resource.getFTPRoot(ALIAS, "wrong", "wrong"); + assertEquals(Response.Status.UNAUTHORIZED.getStatusCode(), response.getStatus()); + } + + private static class UriBuilderMock extends UriBuilder { + // Add the missing method + @Override + public URI buildFromEncodedMap(Map<String, ?> values) { + return URI.create("http://localhost:8080/ftps"); + } + + @Override + public URI buildFromMap(Map<String, ?> values) { + return URI.create("http://localhost:8080/ftps"); + } + + @Override + public URI buildFromMap(Map<String, ?> values, boolean encodeSlashInPath) { + return URI.create("http://localhost:8080/ftps"); + } + + // Change parameter from Class<?> to raw Class + @Override + public UriBuilder path(Class resource) { + return this; + } + + // Change parameter from Class<?> to raw Class + @Override + public UriBuilder path(Class resource, String method) { + return this; + } + + @Override + public UriBuilder path(String path) { + return this; + } + + @Override + public URI build(Object... values) { + return URI.create("http://localhost:8080/ftps"); + } + + @Override + public URI build(Object[] values, boolean encodeSlashInPath) { + return URI.create("http://localhost:8080/ftps"); + } + + @Override + public URI buildFromEncoded(Object... values) { + return URI.create("http://localhost:8080/ftps"); + } + + @Override + public String toTemplate() { + return "http://localhost:8080/ftps"; + } + + @Override + public UriBuilder clone() { + return this; + } + + @Override + public UriBuilder uri(URI uri) { + return this; + } + + @Override + public UriBuilder uri(String uri) { + return this; + } + + @Override + public UriBuilder scheme(String scheme) { + return this; + } + + @Override + public UriBuilder schemeSpecificPart(String ssp) { + return this; + } + + @Override + public UriBuilder userInfo(String ui) { + return this; + } + + @Override + public UriBuilder host(String host) { + return this; + } + + @Override + public UriBuilder port(int port) { + return this; + } + + @Override + public UriBuilder replacePath(String path) { + return this; + } + + @Override + public UriBuilder path(Method method) { + return this; + } + + @Override + public UriBuilder segment(String... segments) { + return this; + } + + @Override + public UriBuilder replaceMatrix(String matrix) { + return this; + } + + @Override + public UriBuilder matrixParam(String name, Object... values) { + return this; + } + + @Override + public UriBuilder replaceMatrixParam(String name, Object... values) { + return this; + } + + @Override + public UriBuilder replaceQuery(String query) { + return this; + } + + @Override + public UriBuilder queryParam(String name, Object... values) { + return this; + } + + @Override + public UriBuilder replaceQueryParam(String name, Object... values) { + return this; + } + + @Override + public UriBuilder fragment(String fragment) { + return this; + } + + @Override + public UriBuilder resolveTemplate(String name, Object value) { + return this; + } + + @Override + public UriBuilder resolveTemplate(String name, Object value, boolean encodeSlashInPath) { + return this; + } + + @Override + public UriBuilder resolveTemplateFromEncoded(String name, Object value) { + return this; + } + + @Override + public UriBuilder resolveTemplates(Map<String, Object> templateValues) { + return this; + } + + @Override + public UriBuilder resolveTemplates(Map<String, Object> templateValues, boolean encodeSlashInPath) { + return this; + } + + @Override + public UriBuilder resolveTemplatesFromEncoded(Map<String, Object> templateValues) { + return this; + } + } +} diff --git a/src/test/java/fil/sr2/flopbox/MyResourceTest.javaTEMPO b/src/test/java/fil/sr2/flopbox/MyResourceTest.javaTEMPO deleted file mode 100644 index 79e09ec41c1f743aa358d9a6a39f6df830b7980a..0000000000000000000000000000000000000000 --- a/src/test/java/fil/sr2/flopbox/MyResourceTest.javaTEMPO +++ /dev/null @@ -1,48 +0,0 @@ -package fil.sr2.flopbox; - -import jakarta.ws.rs.client.Client; -import jakarta.ws.rs.client.ClientBuilder; -import jakarta.ws.rs.client.WebTarget; - -import org.glassfish.grizzly.http.server.HttpServer; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import static org.junit.Assert.assertEquals; - -public class MyResourceTest { - - private HttpServer server; - private WebTarget target; - - @Before - public void setUp() throws Exception { - // start the server - server = Main.startServer(); - // create the client - Client c = ClientBuilder.newClient(); - - // uncomment the following line if you want to enable - // support for JSON in the client (you also have to uncomment - // dependency on jersey-media-json module in pom.xml and Main.startServer()) - // -- - // c.configuration().enable(new org.glassfish.jersey.media.json.JsonJaxbFeature()); - - target = c.target(Main.BASE_URI); - } - - @After - public void tearDown() throws Exception { - server.stop(); - } - - /** - * Test to see that the message "Got it!" is sent in the response. - */ - @Test - public void testGetIt() { - String responseMsg = target.path("myresource").request().get(String.class); - assertEquals("Got it!", responseMsg); - } -}