GSoC 2017 with RedHat
For the last three months I’ve worked on the UnifiedPush Server alongside fellow gsocer Polina to come up with a proof of concept for using Apache Kafka as the UPS’ internal messaging system. Here is a quick a summary of what we did, what can still be improved on and what still has to be done.
- 88 total Jira Tasks created
- 38 pull requests to the UPS
- 7 pull requests to Kafka CDI
- The GSoC branch is 60 commits ahead of the master
What was done
With the help of our mentors, we managed to replace the Java Messaging System with a completely Kafka based workflow for push message routing:
When the Push Notification Sender endpoint is invoked, a Kafka producer in that endpoint produces the request with key/value pair (
InternalUnifiedPushMessage) to the
Notification Routerstreams class is initialized on application startup and begins its work when a message is sent to the above-mentioned topic. After some processing, it streams the push messages out (in the form of a
MessageHolderWithVariantsobject) to 6 different output topics based on the message's variant type (Android, iOS, etc).
MessageHolderWithVariantsKafkaConsumerlistens for messages on the 6 streams output topics and passes them to the
Token Loader. With some further complicated processing, the Token Loader loads batches of tokens from the database for devices that match requested database parameters.
The messages with tokens are dispatched and received by the
MessageHolderWithTokensproducer which produces each message to its respective topic (again, based on variant type).
Finally, we have a
MessageHolderWithTokensconsumer which consumes the
MessageHolderWithTokensobjects and fires a CDI event. This event is handled on the other side by the
NotificationDispatcher, which sends each message to its appropriate push network (Adm, Apns, etc). We decided to stick with CDI events over regular Producers and Consumers to offer an extra layer of abstraction.
We've also looked at Kafka for collecting and processing push related metrics. So far, we have topics for invalid tokens (which will be used for removing them from the database), push message failures and successes, and iOS-specific token failures and successes. We're currently working on a demo application that will read from these topics and perform processing on the data using Kafka Streams.
- Added default generic serializer/deseralizer to handle objects of type
T(#17, mailing list thread #1, mailing list thread #2)
- Unit testing for
serializationpackage (#17, #23)
- Describe installation of Apache Kafka for dev environment on Docker and Openshift (#838, #862, #902, final readme)
- Setup Kafka test environment (#848)
- Implementation of the first Kafka Producer in the
- Integrating the
Kafka CDIlibrary, replacing producers with injection (#857, #861)
- Analysis of codebase with Structure 101 and SonarQube with JaCoCo code coverage (#865, #863, blog post, mailing list thread #1)
- Create a Kafka module for Kafka related configuration and tests (#870)
- Jackson polymorphic serialisation for abstract
Variantclass (#889, mailing list thread #1)
- Update Installation metrics producer (#890)
NotificationDispatcherconsumer (closed, in favour of CDI events abstraction) (#897)
- Use Kafka Streams for push message processing (#900)
- Add a producer for APNS specific token metrics (#908)
- Cleanup and bug fix for
Research & Other
- AGPUSH-2098 Spike for initial Kafka integration
- AGPUSH-2107 Spike for Kafka Stream API usage
- AGPUSH-2104 Research Java EE programming model for Kafka
- AGPUSH-2108, AGPUSH-2148 Research Kafka on Openshift
- AGPUSH-2109 Research Kafka Security
- AGPUSH-2181 Research custom ser/des
- AGPUSH-2110 Spike for Push notification delivery
- AGPUSH-2111 Spike for Push notification Metrics
- AGPUSH-2157 Kafka performance metrics
- Small tweaks to the UPS mock data loader (#5)
- Small tweaks to the Java-ADM library (#5)
- Stream processing demo application
What is left to do
Migration to HBase: Our project diverged naturally from the initial proposal. We encountered several unexpected roadbumps and we ran out of time for database migration (which is a huge task within itself).
Unit and integration testing: The UPS average code coverage percentage is quite low. Ideally I would liked to have be more thorough in the testing of our new branch, and improved the overall test coverage of the master branch. This is something we want to work on in the future.
Kafka Security: Our final goal (as agreed upon with our mentors) was always a working proof of concept, as opposed to a production ready product. The remaining Jiras in our backlog are mostly related to security, which will be worked on after GSoC is over.
All other remaining tickets in our backlog can be found under the
A huge thanks to my mentors, @ziccardi @matzew and @lgriffin for the amount of time, energy and patience they dedicated to us and the project, and thanks to @polinankoleva for being an all round great team-mate!