{"id":14044,"date":"2021-06-10T11:05:21","date_gmt":"2021-06-10T09:05:21","guid":{"rendered":"https:\/\/touk.pl\/blog\/?p=14044"},"modified":"2021-06-10T12:18:02","modified_gmt":"2021-06-10T10:18:02","slug":"touk-hackathon-april-2021","status":"publish","type":"post","link":"https:\/\/touk.pl\/blog\/2021\/06\/10\/touk-hackathon-april-2021\/","title":{"rendered":"TouK Hackathon &#8211; April 2021"},"content":{"rendered":"<p>The last time we wanted to organize a Hackathon our plans were thwarted by &#8220;you know what&#8221;. This state of affairs has lasted so long that we just couldn&#8217;t stand it anymore and launched the next edition of The Hackathon \u2013 remotely. This time we had to cope with new conditions \u2013 not all together in an open space, but everyone at home.  We launched the communicator with a separate room per each project and went into action.<br \/>\nHere we present a brief summary from each team. <!--more--><\/p>\n<h2 id=\"rcb-alert\">RCB Alert<\/h2>\n<p><img decoding=\"async\" src=\"https:\/\/touk.pl\/blog\/wp-content\/uploads\/2021\/06\/hackathon-tcb.png\" alt=\"tcb sms screenshot\" \/> Every now and then we have a problem in our company \u2013 we need to inform everyone that the next day some loud redecorating is to take place or our air conditioning is to be cleaned \u2013 and we had better work remotely that day.<br \/>\nUnfortunately, sometimes our office managers gain this knowledge after our working hours, so there is no channel to notify everyone (hopefully \u2013 no one reads emails at home).<\/p>\n<p>We found a solution to this problem during our last Hackathon.<br \/>\nWe wrote a piece of software that orders an SMS to be sent to each person subscribed to TCB Alerts (it&#8217;s a pun on our government alerts \u2013 RCB).<br \/>\nThis was the easy part \u2013 as we already had an SMS sending service.<br \/>\nHowever, we wanted this solution to be as easy as possible, so our office managers don&#8217;t have to open their laptops, connect to a VPN, search for special forms etc.<br \/>\nWe decided to implement it as a hook to our communicator \u2013 <a href=\"https:\/\/rocket.chat\/\">RocketChat<\/a>.<br \/>\nNow, when our office managers need to inform everyone in the evening, they need only to open the <a href=\"https:\/\/rocket.chat\/\">RocketChat<\/a> app on their phone and type a message on a special channel \u2013 and that&#8217;s it!<\/p>\n<p>We hope that this solution will help us to stay at home and work remotely during the days when it is inconvenient to work from the office.<\/p>\n<h2 id=\"touk-aboutme\">TouK AboutMe<\/h2>\n<p><img decoding=\"async\" src=\"https:\/\/touk.pl\/blog\/wp-content\/uploads\/2021\/06\/hackathon-about-me.png\" alt=\"about me screenshot\" \/> Currently at TouK we have several selfcare services providing information about TouKs (people working or cooperating with TouK).<br \/>\nThe aim of our project was to join these services into one. Of course we know the rule that if you have three separate services then the worst approach is to add a new one. For this reason we enriched the most modern of them with new features such as TouK\u2019s search, adding new information about people, teams information management and much more.<br \/>\nDuring the hackathon our team of four (+ the business owner) learnt a lot about frontend technologies such as <a href=\"https:\/\/en.wikipedia.org\/wiki\/Cross-origin_resource_sharing\">CORS<\/a>, <a href=\"https:\/\/www.mongodb.com\/\">MongoDB<\/a> and <a href=\"https:\/\/en.wikipedia.org\/wiki\/Lightweight_Directory_Access_Protocol\">LDAP<\/a>.<br \/>\nWe all hope that our work will prove to be useful for both current and future TouKs. Our team strove to provide a user experience so seamless that users would wonder at how easy selfcare management could be. We trust that with this hackathon we are a step closer to achieving that goal.<\/p>\n<h2 id=\"business-config-manager\">Business Config Manager<\/h2>\n<p>During our deployments of <a href=\"https:\/\/nussknacker.io\/\">Nussknacker<\/a> we often have the situation that the flow of development of scenarios was done by two teams. One of them is a team called \u201cConfigurators\u201d \u2013 people who are close to business requirements but also with quite a high level of technical skills. Those people are responsible for the development of scenarios on the Nussknacker side. On the other hand, the second team is made up of Business members, those with lower technical skills but with a good knowledge of customer needs.<br \/>\nConfigurators want to outsource some steps of development to business \u2013 so some changes can be made faster, without involving Configurators in the process. We found out that we should make a tool that can give Configurators the ability to create definitions of some configurations and after that, Business can fill in the values of those configurations. In the end, this configuration will be used in some steps of the scenario in Nussknacker.<\/p>\n<p>After the deployment of the proof of concept, we realized that it is necessary to handle some important things:<\/p>\n<ul>\n<li>Both definitions of configurations and values should be versioned and have some audit information, such as the author and time of the change.<\/li>\n<li>Migrations of changes in definitions should be painless.<\/li>\n<li>We should support many types of properties: from raw strings to some date time pickers and so on.<\/li>\n<li>Configurations should have a lifecycle, so new ideas can be deployed on a lower environment and after some tests can be promoted to higher env.<\/li>\n<\/ul>\n<p>After brainstorming before the Hackathon, we decided to use modern stack, but with some solid, battle-tested components:<\/p>\n<ul>\n<li>Java 15<\/li>\n<li><a href=\"https:\/\/spring.io\/projects\/spring-boot\">Spring Boot 2.4<\/a> <\/li>\n<li><a href=\"https:\/\/projectreactor.io\/\">Project Reactor<\/a> <\/li>\n<li><a href=\"https:\/\/www.postgresql.org\/\">Postgresql 13<\/a><\/li>\n<li><a href=\"https:\/\/r2dbc.io\/\">R2DBC<\/a><\/li>\n<li><a href=\"https:\/\/reactjs.org\/\">ReactJS<\/a> <\/li>\n<li><a href=\"https:\/\/github.com\/rjsf-team\/react-jsonschema-form\">react jsonschema-form<\/a> <\/li>\n<\/ul>\n<p>We also designed the domain level of application.<\/p>\n<p>On the first day of the Hackathon, we started with pair programming. We tried to go through all layers of the application to make sure that everyone in the team has a common vision of what the architecture will look like. After that we split the work into four separate parts:<\/p>\n<ul>\n<li>Management of definitions <\/li>\n<li>Management of values<\/li>\n<li>Nussknacker integration with Business Config Service <\/li>\n<li>Web application Finally, we integrated all the features together and completed the MVP step.<\/li>\n<\/ul>\n<p>The project ended successfully. We proved that our design was correct, prepared a solid foundation for future development, and had a lot of fun designing the architecture and testing new tools.<\/p>\n<h2 id=\"nussknacker-serverless\">Nussknacker Serverless<\/h2>\n<p>Most of you probably know <a href=\"https:\/\/nussknacker.io\/\">Nussknacker<\/a> \u2013 a powerful platform which allows non-technical users to author and deploy streaming scenarios on <a href=\"https:\/\/flink.apache.org\/\">Apache Flink<\/a>.<br \/>\nBut Nussknacker Designer can also describe more business rules-oriented scenarios \u2013 used e.g. in recommendations or NBA domains. In this case, the scenario is deployed as a REST microservice. During the Hackathon we decided to make this setup more <a href=\"https:\/\/kubernetes.io\/\">Kubernetes<\/a>\/Serverless-oriented. We decided that a Nussknacker scenario is a good candidate for <a href=\"https:\/\/kubernetes.io\/docs\/tasks\/extend-kubernetes\/custom-resources\/custom-resource-definitions\/\">K8 CRD<\/a> and that <a href=\"https:\/\/knative.dev\/\">KNative<\/a> will provide us with a serverless deployment platform.<br \/>\nIn two days we reached most of our goals:<\/p>\n<ul>\n<li>Nussknacker creating scenario ConfigMap during deployment (in the future it will be CRD)<\/li>\n<li>Custom Kubernetes operator\/controller which transforms scenario ConfigMap into KNative service (scaling down to zero if needed :))<\/li>\n<li>Simple REST microservice image, which serves the scenario<\/li>\n<li>Everything deployed via <a href=\"https:\/\/helm.sh\/\">Helm<\/a>\/<a href=\"https:\/\/about.gitlab.com\/\">GitlabCI<\/a> to our <a href=\"https:\/\/www.digitalocean.com\/products\/kubernetes\/\">DigitalOcean K8 cluster<\/a><br \/>\nWe are also pretty excited about the next steps \u2013 scenario observability (metrics, statuses), CRDs and making our serving image serverless ready &#8211; by using <a href=\"https:\/\/www.graalvm.org\/\">GraalVM<\/a> native images.<br \/>\nHopefully, in the short to medium term, all of this will be accessible with our Nussknacker offering.<\/li>\n<\/ul>\n<h2 id=\"musicbox\">MusicBox<\/h2>\n<p><img decoding=\"async\" src=\"https:\/\/touk.pl\/blog\/wp-content\/uploads\/2021\/06\/hackathon-music-box.png\" alt=\"music box screenshot\" \/> We have created a minimalistic web app for generating music in a loop based on text input.<br \/>\nThe idea is to make writing music as easy as possible. E.g. <code>|k h s h |<\/code> is the most basic percussive beat, while <code>|Am|C|<\/code> gives a basic chord progression. Furthermore, there&#8217;s a collaborative mode (think jam sessions ;).<\/p>\n<p>Frontend:<\/p>\n<ul>\n<li><a href=\"https:\/\/www.typescriptlang.org\/\">TypeScript<\/a> <\/li>\n<li><a href=\"https:\/\/www.snowpack.dev\/\">SnowPack<\/a> <\/li>\n<li>WebSocket <\/li>\n<li><a href=\"https:\/\/tonejs.github.io\/\">Tone.js<\/a> (music generation)<\/li>\n<\/ul>\n<p>Backend:<\/p>\n<ul>\n<li><a href=\"https:\/\/kotlinlang.org\/\">Kotlin<\/a> <\/li>\n<li><a href=\"https:\/\/spring.io\/\">Spring<\/a><\/li>\n<\/ul>\n<h2 id=\"summary\">Summary<\/h2>\n<p>In our opinion, The Hackathon was successful and fulfilled its task \u2013 that is, it allowed us to take a short break from our more important work and experiment with various fun technologies in good company. The fact that during the Hackathon team members were in a voice chat with each other certainly played a big role, which to some extent allowed us to build an atmosphere of cooperation in the fight against challenges.<br \/>\nWe are already looking forward to the next hackathon \u2013 hopefully, this time on site.<\/p>\n<p>If you want, <a href=\"https:\/\/touk.pl\/blog\/2019\/04\/02\/touk-hackathon-2019-1\/\">here<\/a> you can see what we did during the previous edition.<\/p>\n","protected":false},"excerpt":{"rendered":"The last time we wanted to organize a Hackathon our plans were thwarted by &#8220;you know what&#8221;. This&hellip;\n","protected":false},"author":77,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[573,622],"class_list":{"0":"post-14044","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-development-design","7":"tag-hackaton","8":"tag-nussknacker"},"_links":{"self":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts\/14044","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/users\/77"}],"replies":[{"embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/comments?post=14044"}],"version-history":[{"count":37,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts\/14044\/revisions"}],"predecessor-version":[{"id":14746,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts\/14044\/revisions\/14746"}],"wp:attachment":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/media?parent=14044"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/categories?post=14044"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/tags?post=14044"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}