1
0
Fork 0

Compare commits

...

3 Commits

@ -1,6 +1,6 @@
# Java exercise for the backend recruiting process
# Solution to the Java exercise for the backend recruiting process
## Prerequisites
## Running the application
1. Make sure you have a working Java development environment. The Maven configuration of the boilerplate requires at least Java 11.
2. Clone this repository and don't fork as your code would be visible to other candidates in case you choose to push your implementation to a public repository.
@ -9,14 +9,6 @@
5. Test the API by fetching data from the status resource by executing `curl http://localhost:8282/status`.
6. If any of the above fails you need to revisit your development environment or talk to [hannes@metasolutions.se](mailto:hannes@metasolutions.se) (it may be a bug).
## Boilerplate
As you could see as the result of 5. above, the boilerplate is a very basic, but fully functional implementation of a REST API. The boilerplate is built using the [Restlet framework](https://restlet.talend.com/). You may find its documentation of the [resource architecture](https://restlet.talend.com/documentation/user-guide/2.4/core/resource/overview) and the [server tutorial](https://restlet.talend.com/documentation/user-guide/2.4/introduction/first-steps/first-application) useful.
There are only two REST resources: a status resource that attaches to `/status` and a default resource that responds at `/`.
Implementing a new resource involves creating a new class (see `StatusResource.java` as example) and adding it to the router in `RestApplication.java`.
## Exercise
1. Implement a new resource `/echo` that responds with the request body when posting (HTTP POST) to it; it should simply mirror the request back as response.
@ -42,3 +34,52 @@ If anything is unclear or if you get stuck somewhere in the exercise, do not hes
## Result
Document your implementation in Text or Markdown format and send it along with your code as a tar.gz archive to [Hannes](mailto:hannes@metasolutions.se). You can also send a link to a Git repository.
## Solution
The `/echo` endpoint will convert any data posted with `Content-Type: text/csv` and `Accept: text/html` to a simple html table.
All other data will be echoed back unchanged. Empty datasets will return an explanatory message.
* `RestApplication.java`
* New router added for path `/echo`
* `resources/EchoResource.java`
* `POST` requests are handled depending on `Content-Type`. CSV-data is handled by the `tablify` method, all others by the `echo` method
* The `tablify` method:
* Checks for `Accept: text/html` to determine if table conversion should be performed. Requests that do not match are treated like other `Content-Type`s.
* Assumes the CSV format in the example.
* Returns an explanatory string if POST data is missing or cannot be parsed.
### Example use
``` bash
$ cat test.csv
title,description,created
Important document,This is an important document,2022-03-31
Less important document,,2022-03-31
Last document,,
$ curl -H 'Content-Type: text/csv' -H 'Accept: text/html' -X POST --data-binary @test.csv http://localhost:8282/echo
<table>
<tr>
<td>title</td>
<td>description</td>
<td>created</td>
</tr>
<tr>
<td>Important document</td>
<td>This is an important document</td>
<td>2022-03-31</td>
</tr>
<tr>
<td>Less important document</td>
<td></td>
<td>2022-03-31</td>
</tr>
<tr>
<td>Last document</td>
<td></td>
<td></td>
</tr>
</table>
$ curl -X POST -d "Example string" http://localhost:8282/echo
Example string
```

@ -2,7 +2,9 @@ package se.metasolutions.recruit;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.config.Configurator;
import org.restlet.routing.TemplateRoute;
import se.metasolutions.recruit.resources.DefaultResource;
import se.metasolutions.recruit.resources.EchoResource;
import se.metasolutions.recruit.resources.StatusResource;
import org.json.JSONException;
import org.json.JSONObject;
@ -59,6 +61,7 @@ public class RestApplication extends Application {
// global scope
router.attach("/status", StatusResource.class);
router.attach("/", DefaultResource.class);
router.attach("/echo", EchoResource.class);
return router;
}

@ -0,0 +1,70 @@
package se.metasolutions.recruit.resources;
import org.restlet.data.MediaType;
import org.restlet.representation.BufferingRepresentation;
import org.restlet.representation.Representation;
import org.restlet.representation.StringRepresentation;
import org.restlet.resource.ResourceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.restlet.resource.Get;
import org.restlet.resource.Post;
import java.io.IOException;
public class EchoResource extends BaseResource {
private final static Logger log = LoggerFactory.getLogger(EchoResource.class);
@Post()
public Representation echo(Representation entity) throws IOException {
return getEchoResponse(entity);
}
@Post("csv")
public Representation tablify(Representation entity) throws IOException {
Representation response;
if (!getRequest().isEntityAvailable()) {
response = new StringRepresentation("No POST data available");
} else {
String acceptedMediaTypes = getClientInfo().getAcceptedMediaTypes().toString();
if (acceptedMediaTypes.contains("text/html")) {
StringBuilder htmlTable = new StringBuilder("<table>\n");
try {
Representation data = new BufferingRepresentation(entity);
String csv = data.getText();
String[] rows = csv.split("\\r?\\n");
for (String row : rows) {
htmlTable.append("<tr>\n");
String[] cells = row.split(",", -1);
for (String cell : cells) {
htmlTable.append("<td>").append(cell).append("</td>\n");
}
htmlTable.append("</tr>\n");
}
} catch (IOException e) {
htmlTable.append("<tr><td>Error while reading CSV data</td></tr>");
} finally {
htmlTable.append("</table>\n");
}
response = new StringRepresentation(htmlTable);
response.setMediaType(MediaType.valueOf("text/html"));
} else {
response = getEchoResponse(entity);
}
}
return response;
}
Representation getEchoResponse(Representation entity) throws IOException {
String responseText = "";
try {
BufferingRepresentation data = new BufferingRepresentation(entity);
responseText = data.getText();
} catch (IOException e) {
responseText = "Error while reading text data";
} finally {
return new StringRepresentation(responseText);
}
}
}
Loading…
Cancel
Save