descriptionnone
ownerjane.lx.gay@gmail.com
last changeSat, 9 Mar 2019 02:29:51 +0000 (8 18:29 -0800)
content tags
add:
README.md

Chat server exercise 1.2 notes

The primary focus of this document is on explication of existing code and suggestions for improving robustness and clarity rather than to speculate about a feature-rich chat experience.

Building and running the server

Running gradle build will bundle an executable uber jar in build/libs.

To run the integration test: gradle integrationTest

Usage:

$ java -jar build/libs/signal-rest-api-exercise-v1.2-all.jar -h
Usage: simple-chat-server [-hV] [-a=ADDRESS] [-f=DB_FILE] -p=PORT
Starts the chat server.
  -a, --address=ADDRESS   server address (default: localhost)
  -f, --dbFile=DB_FILE    path to a file where the chat db is stored (default:
                            chats_testing.db)
  -h, --help              Show this help message and exit.
  -p, --port=PORT         server port
  -V, --version           Print version information and exit.

Alternatively, gradle run will execute the main method as well.

Examples:

listen only on localhost:

$ java -jar build/libs/signal-rest-api-exercise-v1.2-all.jar -a localhost -p 6000
... INFO : e.n.c.s.h.d.Dispatcher loaded 2 route handlers
... INFO : e.n.c.s.Server loaded 200 users from contacts
... INFO : e.n.c.s.a.Listener Listening on /127.0.0.1:6000

listen everywhere and specify a db (requires privilege to bind port 80):

$ java -jar build/libs/signal-rest-api-exercise-v1.2-all.jar -a :: -p 80 --dbFile /var/run/simple-chat/chats.db
... INFO : e.n.c.s.h.d.Dispatcher loaded 2 route handlers
... INFO : e.n.c.s.Server loaded 200 users from contacts
... INFO : e.n.c.s.a.Listener Listening on /0:0:0:0:0:0:0:0:80

Server endpoints, protocol, request / response

See schemas/ for JSON schemas of chat and message.

POST /chats creates a chat between two users:

POST /chats HTTP/1.1
Host: localhost:3335
User-Agent: curl/7.64.0
Accept: */*
Content-Length: 54
Content-Type: application/json

{
    "id": 1,
    "participantIds": [51201, 28463]
}
---
HTTP/1.1 200 OK

GET /chats?userId={userId} retrieves a user's chats:

GET /chats?userId=28463 HTTP/1.1
Host: localhost:3335
User-Agent: curl/7.64.0
Accept: */*
---
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 41
Content-Encoding: identity

[{"id":1,"participantIds":[51201,28463]}]

POST /chats/{chatId}/messages adds a message to a chat

POST /echo HTTP/1.1
Host: localhost:3335
User-Agent: curl/7.64.0
Accept: */*
Content-Length: 172
Content-Type: application/json

{
    "id": "6cfd98ae-ab8a-4722-a385-dad87e5f0207",
    "timestamp": 101,
    "message": "Hi, how's it going?",
    "sourceUserId": 28463,
    "destinationUserId": 51201
}
---
HTTP/1.1 200 OK

GET /chats/{chatId}/messages retrieves the messages in a chat

GET /chats/1/messages HTTP/1.1
Host: localhost:3335
User-Agent: curl/7.64.0
Accept: */*
---
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 270
Content-Encoding: identity

[{"id":"0d1e05a1-0b57-44a7-967a-1d7415cbedec","timestamp":100,"message":"Hello!","sourceUserId":51201,"destinationUserId":28463},{"id":"6cfd98ae-ab8a-4722-a385-dad87e5f0207","timestamp":101,"message":"Hi, how's it going?","sourceUserId":28463,"destinationUserId":51201}]

Program structure

Package layout

Next Steps

Code organization and modularity

Consider using an injection framework to achieve decoupling between server, controller, instrumentation, and data components. At present, the listener and dispatcher are decoupled from the application logic by non standardized use of reflection to search for annotations that bind routing and priority data to an interface type known to the dispatcher.

Consider using a lifecycle manager such as Spring to ensure that startup and shutdown occurs in a graceful and orderly manner.

Add timing and count metrics for use with profiling and assessing performance.

Add a coverage tool and increase unit testing such that line coverage is 100% and branch coverage is > 90%.

Architecture

Chat protocol

The protocol and schemas should be versioned.

User chats are presently returned in an arbitrary order. This is okay in the likely case that each front end instance is expected to maintain its own ordering. It may be nice to allow chats to be ordered by creation time, which would require an update to the schema.

An endpoint should be added to allow users to request to be contacts.

Storage

To achieve horizontal scaling with a DB such as Postgres, data can be partitioned. Chat data lends itself relatively well to partitioning.

With a storage system designed for horizontal scaling such as DynamoDB, it is a requirement to be able to perform consistent reads (which DynamoDB does provide).

Caching

Individual messages are immutable and may be cached indefinitely. The server should return cache control headers and allow a 304 response for GET /chat/{chatId}/messages. (Even with theoretically infinitely cacheable data, it is best to set a cache timeout of at most 30 minutes.) It would be beneficial to paginate message responses and allow incremental message retrieval.

It is unclear whether chats are indefinitely cacheable as it is possible to relax the restriction on participantIds to allow more than two participants.

Security

Users should be authenticated and only authorized to access chats in which they are participants and messages of those chats.

Server scaling, performance, and robustness

The server should better support HTTP/1.1 including common Content-Encodings such as gzip, Transfer-encoding chunked.

Support HTTP 2.

Profile against expected and abnormal request loads and tune accordingly.

Since routes are static at runtime, an in memory cache of routes matching paths could be useful depending on profiling about time used matching paths.

shortlog
2019-03-09 Ismay Jane GayAdd a note to the readme about the need for unit test... master
2019-03-09 Ismay Jane GayAdd schemas that were provided with the exercise
2019-03-09 Ismay Jane GayAdd a readme
2019-03-08 Ismay Jane GayGet /chats?userId={} now returns a list of chats instea...
2019-03-08 Ismay Jane GayCheck for existing users when loading users from contac...
2019-03-08 Ismay Jane GaySend correct Content-Length header for echo responses
2019-03-08 Ismay Jane GayUse non-default test dbs for unit and integ tests
2019-03-08 Ismay Jane GayUpdated javadoc
2019-03-08 Ismay Jane GayProvide default values for optional cli args
2019-03-08 Ismay Jane GayAdd log4j2 config and have Listener log address/port...
2019-03-08 Ismay Jane GayAdd Listener#awaitReady using a CountDownLatch, accessi...
2019-03-08 Ismay Jane GayAdd javadoc task to build
2019-03-08 Ismay Jane GayRename test file
2019-03-08 Ismay Jane GayAllow db file to be set prior to initialization
2019-03-08 Ismay Jane GayChange User chatIds from list to set
2019-03-08 Ismay Jane GayFix bug w/ cli args, add tests, fix loading user contac...
...
heads
5 years ago master