A minimal file server based on Akka Http. The project has been built keeping in mind, a service that can be built within approx 4-5 hours.
- The service has a single endpoint with the following signature and request body structure POST /api/server/create {"requestId": "a random alphanumeric string (S1)"}
- The endpoint is rate limited - it only accepts 2 request / s / unique resourceId
- The endpoint creates a local file but it takes 5-10s to create it (no less than 5s, no longer than 10s). The value of the file content is another random alphanumeric string (S2).
- The endpoint responds immediately with either
Output: A: {"requestId”: "{{S1}}", "created": true, "fileContent": "{{S2}}"} - if the time resource was created or B: {"requestId”: "{{S1}}", "created": false} - if the time resource was not created or C: HTTP response code 429 (Too Many Requests) and an empty body if rate limit was exceeded
- Idiomatic approach, using custom code than Akka streams.
- Akka HTTP based application exposing a single route with Post method POST /api/server/create.
- Use Custom direction to manage Rate limiting and internal threadsafe cache to keep track of request and resource.
- Use Akka Actor for async calls and adding 5s delay.
- Store file in a central location.
- Since currently we do not have a criteria to identify a unique resource, only for test purpose
- We assume the requestId as the unique resource.
- Can be further extended to create a checksum of whatever request entities we require.
- The time duration of the rate limit is currently based on the function/service call.
- Max no of request when the server is processing a single resource (requestID)
- Can be extended to take a specific time duration via the directive.
- When a user calls the API, a file is created in a central location and random generated fileContent is returned as the response for a unique requestId with 200 status code.
- When a user calls the API with previous requestId, a new file is created in a central location and random generated fileContent is returned with 200 status code.
- When a user makes more than 2 consecutive calls, when the server is processing the previous request, an empty response with 429 (Too many request) status code is returned.
- When a user calls the API and error occurs in the server, an empty response with 500 (Internal error) status code is returned.
You need to download and install sbt for this application to run.
Once you have sbt installed, type/run the following command in the terminal:
sbt run
or
Run via IDEPost Url: http://127.0.0.1:8080/api/server/create
Request Body: { "requestId":"testRequest1" }
- Rate limiting is based on server processing time (Reason- Server takes a min 5s, which would lead to failing multiple requests).
- Rate Limiting can be extended by adding timestamp check when fetching from cache for a specific duration.
- Unit and Integrations tests can be better used for edge cases.
To run Unit test:
sbt test
or
Run test via IDETo run Integration test: Prerequisites:
- File-Server should be online or will throw 500 error.
- Using single conf file so testing will also create file in the same central directory (will not work if central dir value is wrong in config.)
- File will be created and deleted after IT is completed. (File name: "t_e_s_t_file_dont_use.txt")
- Both services should have different file location.
sbt it:test
or
Run it test via IDEThe custom directive idea has been taken from https://gist.github.com/johanandren/b87a9ed63b4c3e95432dc0497fd73fdb However instead of using AtomicNumber, we are using a threadSafe map (ConcurrentHashMap)