Diese Woche haben wir hart mit unserem Backend gekämpft, d.h. mittlerweile haben wir Spring Boot Data abgeschworen und begonnen unsere eigene Lösung zu implementieren.
Mit dieser Lösung haben wir auch bereits in ABAP gearbeitet. Nicht unbedingt eine Referenz. Allerdings kennen wir uns damit aus.
Wir haben also begonnen ein generisches Data Access Object zu implementieren. Von count, exists über findAll, delete, reload bis hin zu save haben wir alle möglichen Datenbank-Funktionen in einem Framework verschalt. Die Idee war vorerst sich grundsätzlich nur mit JDBI / JDBC auseinanderzusetzen. Das bisherige Ergebnis ist aber mehr. Ein kleines Framework, welches wir zukünftig für viele Entitäten nutzen können und das vielleicht Spring Boot Data ablöst.
Bis dahin ist es noch ein weiter weg. Aber die Implementierung macht uns viel Spaß.
Mittlerweile haben wir auch mit Annotations für unser Framework begonnen. Damit fühlt sich die Entwicklung langsam wir wirkliche Framework Implementierung an.
Autor: outlivethesun
2021-08-24 Good Bye, Maven
„Good Bye, Maven“ heißt das neue Achievement, das wir uns gegönnt haben. Und das kurz nach „Good Bye, Spring Tool Suite and Java“.
Denn diesen Sprint haben wir weiter umgestellt, gerefactored, Technologien über den Haufen geworfen. Im letzten Sprint ging es Spring Tool Suite an den Kragen. Stattdessen setzen wir jetzt sowohl fürs Frontend (Android), als auch für das Backend (Spring Boot) auf Intellj mit Kotlin.
Schluss mit der Umstellung auf die gerade notwendige IDE. Schluss mit der Umstellung auf die gerade erforderliche Syntax. Und teilweise Schluss mit der Umstellung auf die gerade benötigten Tools und APIs. Denn bspw. können wir nun auch für das Backend auf Mockk setzen, das wir seit ein paar Monaten für unsere Frontend-Entwicklung schätzen gelernt haben.
Last but not least kam für das Backend immer noch „Maven“ und im Android Studio „Gradle“ zum Builden unserer Anwendungen zum Einsatz. Da wir schon länger von Gradle überzeugt sind, es leserlicher und leichter handhabbar finden, wird nun auch das Backend gegradled.
Die Umstellung an sich war gar nicht so einfach. Denn einerseits wollten wir das Projekt komplett neu aufbauen, um nicht dem Risiko ausgesetzt zu sein, dass unser Projekt zwar Gradle unterstützt aber noch alten Fetzen / Leichen / Reste von Maven enthält, aber auf der anderen Seite wollten wir auch nicht unsere Git-Historie verlieren. Hm, was nun? Aber da hatte Verena eine super Idee und ein frisches Gradle Projekt erstellt, das Coding aus unserem Maven Projekt übernommen und anschließend die Inhalte aus dem neuen Gradle Folder in das alte, aber mittlerweile geleerte Maven Folder kopiert, an dem … genau … aber noch die Git-Historie hängt. Works!!!
Die letzte Hürde war die Java JDK Version. Aber das ist eine andere Geschichte.
Mittlerweile haben wir die komplette Anwendung (Backend inkl. Frontend) auf unseren beiden Systemen wieder zum Laufen bekommen.
Was lief noch? Da wir für das Backend immer noch eine datenbanknähere Lösung „suchen“, haben wir fleißig gelesen und gestöbert, wie andere ihre ORMs implementieren und wie ihre Frameworks funktionieren. Eine endgültige Lösung haben wir noch nicht, denn die funktionieren teilweise relativ unterschiedlich und haben unterschiedliche Vor- und Nachteile, wie bspw. eine Lösung alla Entity Framework vs. JDBC. Aus den Augen dürfen wir dabei auch nicht den Entwicklungsaufwand für uns lassen. Denn wenn wir uns nun von Spring Boot JPA abwenden, wollen wir die Probleme, die wir damit hatten lösen, aber auch nicht alles nachprogrammieren. Aber da machen wir kommende Woche weiter.
Jetzt sind wir auf jeden Fall mega happy über unsere in Intellj gegradlete Kotlin Anwendungen, die von Mockk getestet werden.
2021-08-17 Long time no see
Wir sind zurück aus der kreativen Sommerpause und haben uns sofort an unser altes Problem gesetzt, allerdings mit einem neuen Ansatz. Mittlerweile sind wir uns einig, dass wir mit Hibernate beziehungsweise Spring Data JPA an die Grenzen des Machbaren gestoßen sind und wir die Queries lieber selbst in die Hand nehmen wollen. Dafür haben wir begonnen uns mit JDBC beschäftigt und sind dabei rein zufällig über ein Video gestolpert, dass uns vom eigentlichen Thema abgelenkt hat:
Wir dachten bisher, dass wir uns vorerst für unsere Backend-Entwicklung mit der Spring Tool Suite begnügen müssten, da wir Spring verwenden und dies in IntelliJ in der Community Edition nicht unterstützt wird. Der Wechsel vom Android Studio, basierend auf IntelliJ, auf die Spring Tool Suite, basierend auf Eclipse, ist jedes Mal eine Umgewöhnung, da nicht alle Tastenkombis existieren und auch so macht es einfach mehr Spaß, in IntelliJ als in Eclipse zu programmieren, da die IDE viel intelligenter ist. Wir hatten auch schon einmal versucht, wenigstens Kotlin in der Spring Tool Suite zum Laufen zu bringen, damit wir nicht auch noch von Kotlin auf Java switchen müssen, aber die Sprachunterstützung war mehr als dürftig. Im Video wurde erwähnt, dass man sich auf https://start.spring.io/ ein Spring-Projekt konfigurieren kann und dieses dann mit jeder Version von IntelliJ öffnen kann. Also haben wir unser Projekt genommen, es in IntelliJ geöffnet und uns im gleichen Zuge an den Umzug nach Kotlin gemacht. Dafür gibt es eine nette Funktion in IntelliJ, um Java-Code in Kotlin-Code umzuwandeln, aber es brauchte trotzdem noch einiges an Handarbeit und hat uns fast einen Tag lang beschäftigt. Es gibt noch einige Fehler beim Starten des Projektes, aber wir sind zuversichtlich, dass wir das Projekt nächste Woche zum Laufen bekommen.
2021-06-22 Beauty-Kur
NamedEntityGraphes sind Müll :D. Wir hatten einfach keine Lust mehr an unserem Problem weiterzuarbeiten, das uns schon die letzten zwei Wochen beschäftigt hat.
Stattdessen haben wir diese Woche wieder etwas Schönes gemacht, etwas das uns Spaß macht, etwas bei dem ein Fortschritt zu sehen ist, bei dem einem das Herz aufgeht. Die letzten zwei Tage haben wir das UI der App umgestaltet. D.h. wir haben Farben vereinheitlicht, unsere eigene Farbpalette erweitert, neue Farbkombinationen ausprobiert und das Layout für Challenges und Achievements überarbeitet.
Die Challenges werden nun listartig mit einer Challenge pro Zeile angezeigt. Außerdem hat eine Challenge einen Schwierigkeitsgrad verpasst bekommen. Der Schwierigkeitsgrad kann leicht, mittel oder schwer sein. Anhand von Sternen und Medaillenfarben wird er rechts auf dem Listitem einer Challenge angezeigt.
Die Details der Challenges haben wir farblich angepasst und den Schwierigkeitsgradindikator hinzugefügt.
Außerdem haben wir uns um die Achievements gekümmert. Die Liste sieht nun wie folgt aus:
Und zu guter Letzt ist die Achievement Details Anzeige überarbeitet worden. Hier haben wir uns an die Details der Challenges orientiert. Eine Überlegung, die momentan im Raum steht, ist, die Details für Achievements ggf. komplett verschwinden zu lassen.
Alle anderen Komponenten sind von den Design Änderungen ebenfalls betroffen. So sieht derzeit das Dashboard aus.
Ansonsten haben wir versucht unsere üblichen Weekly Aufgaben abzuarbeiten und haben Bugs gefixt, Unit Tests geschrieben und unsere Words of the Day abgefragt.
2021-06-15 Mitten durch die „Messy Middle“
Wir haben weiter an den Challenges gearbeitet. Grundsätzlich würden wir uns gerne auf die Umsetzung konzentrieren, um die Challenges und alles was dazu gehört zu implementieren. Stattdessen kämpfen wir momentan mit Spring Boot und im Speziellen Spring Data JPA. Scheinbar hatten wir vorher nie Entitäten, die zwei Relationen zu anderen Entitäten hatten. In unserem Fall haben User sowohl Achievements, als auch neuerdings Challenges.
Bereits letzte Woche haben wir mit einer LazyInitializationException gekämpft und wussten nicht weshalb sie auftritt. Diese Woche haben wir zumindest die Ursache gefunden. Um den Fehler nachzustellen, haben wir ein komplett neues Beispiel implementiert und nach und nach Komplexität hinzugefügt, bis der Fehler auftrat.
Letztendlich würde das oben beschriebene Datenmodell problemlos funktionieren, wenn man darauf rein im Controller zugreifen würde. In unserem Fall nutzen wir aber die Annotation @PostConstruct, um beim Starten des Servers ein Testszenario aufzubauen. Hier liegt der Hund begraben. Scheinbar werden bei Zugriffen über die Repositories teilweise neue Sessions gespawnt. Werden Datenzugriffe aus unterschiedlichen Sessions gemischt (bspw. laden der User und separat: gib mir alle Challenges zum User) kommt es zur Exception.
Wir haben versucht das Problem auf unterschiedlichsten Arten zu lösen, aber haben es bis heute nicht hinbekommen. Lösungen waren bspw. die Verwendung von NamedEntityGraphes, Queries im Repositories, die Objekte der Sessions zu syncen und noch viele kleinere Versuche.
Es läuft momentan darauf hinaus, dass wir Spring Data JPA durch ein anderes SQL Framework ersetzen müssen.
Mehr gibt es diese Woche auch nicht zu berichten.
2021-06-08 Challenges „die Zweite“ – oder – langsam zurück zur „Messy Middle“?
Diese Woche gibt es gar nicht so viel zu berichten. Wir haben etwas Brainstorming bezüglich der Challenges und wo es mit ihnen hingehen soll betrieben. Außerdem haben wir weiter am Umbau bzw. dem Split der Achievements in Challenges gewerkelt und neben dem Backend sind die Challenges jetzt auch das Frontend-Model vorhanden. Wir können uns jetzt die Challenges abholen und anzeigen, aber der Umbau der Contribute-Funktion erweist sich als schwieriger als angenommen. Hier müssen wir noch einmal zurück ans Board. Wir haben uns vorgestellt, dass man beim Abschluss einer Challenge ein Achievement erhält. Wir würden allerdings auch gerne vorsehen, dass für ein Achievement mehrere Challenges nötig sind. Hier stoßen wir mit unseren Iterationen über unser Model langsam an Grenzen und müssen uns demnächst über unsere eigenen Selects Gedanken machen. Eigentlich hatten wir bereits diese Woche das Vergnügen und haben uns darin versucht, sind aber schon an einem vermeintlich einfachen Beispiel gescheitert: Bisher hatte ein User eine Liste von Achievements als Relation. Als wir diese definiert haben, sind wir auf einen Lazy-Load-Fehler bei der Initialisierung gestoßen (wenn man dem Internet Glaube schenken möchte, DER häufigste Fehler überhaupt in diesem Zusammenhang). Um diesen zu fixen, hatten wir durch Stackoverflow-Suche auf den Fetch-Typ „EAGER“ umgestellt und mit einem Kommentar versehen, dass wir uns für die Zukunft eine bessere Lösung überlegen müssen. Jetzt war die Zukunft, denn als wir dem User eine neue Relation „Challenges“ spendieren wollten, haben wir festgestellt, dass sich nur eine Relation „eager“ laden lässt. Darauf hin haben wir etliche Versuche unternommen, unsere eigene Select-Logik zu hinterlegen, was für eine solch einfache Beziehung eigentlich ein Kinderspiel sein sollte, sind über zahlreiche Lösungen gestolpert, die nicht funktioniert haben und haben das Thema für diese Woche mangels Suchbegriffen ad acta gelegt.
2021-06-01 Bauprojekt „Challenges“ begonnen
Nachdem wir uns letzte Woche noch einmal eine Auszeit gegönnt haben, ging es diese Woche mit verschiedenen Themen weiter.
Am Montag haben wir uns dem Thema Rubber Stamps gewidmet. Für abgeschlossene oder abgelaufene Achievements / Challenges wollten wir einen Stempel wie „Completed“ oder „Expired“ anzeigen.
Da wir es gewohnt sind rumzuprobieren, ging es dieses Mal mit Gimp zur Sache, nachdem Powerpoint 😀 nicht das gewünschte Ergebnis geliefert hat. Und das Ergebnis kann sich aus unserer Sicht sehen lassen.
Wurde eine Challenge abgeschlossen, wird nun in dick und fett und grün „Completed“ geschrieben. Ist eine Challenge abgelaufen gibt es ein rotes „Expired“.
Außerdem dachte wir uns, es wäre schick, wenn eine neu hinzugefügte Challenge auch als solche in der Übersicht gekennzeichnet wird. In diesem Fall wird der Schriftzug „New“ angezeigt. Allerdings muss noch eine Bedingung hinterlegt werden, ab wann der Schriftzug entfällt. Die Implementierung für Completed und Expired sind hingegen abgeschlossen, d.h. der Status der Challenge wird berücksichtigt.
Was sonst? Neben kleineren Aufgaben, wie an unserer Unittestabdeckung zu arbeiten, ging es vor allem an die Ideen für Challenges.
Achievements sind eine Belohnung, aber eine Challenge ist etwas, woran gearbeitet wird. So wollen wir das auch umsetzen. Erledigt man eine Challenge gibt es möglicherweise ein Achievement. Möglicherweise gibt es Daily oder Weekly Challenges. An Details sind wir noch dran.
Mit der Implementierung des Backends haben wir begonnen. Das Rad müssen wir jedoch nicht neu erfinden, denn grob genommen sind unsere heutigen Achievements zukünftige Challenges, an denen man arbeiten und contributen kann.
Neben der Bereitstellung des Models, Serviceklassen und Builder haben wir auch die Struktur für die Challenges überarbeitet, denn für die Achievements ist die Struktur mit der Zeit doch unübersichtlich geworden.
Im kommenden Sprint müssen wir uns noch einmal anschauen, was wir zusätzlich abstrahieren können. Denn da die Achievements als Entität bleiben, haben wir nun teilweise Interfaces und Klassen, die ähnliche Aufgaben haben. Aber darüber berichten wir sicherlich in 7 Tagen.
2021-05-18 Contributen ist nun zeitlich beschränkt
Wo wart ihr letzte Woche? Wir waren nicht hier und haben uns stattdessen eine Denkpause genommen.
Dafür haben wir diese Woche umso mehr geschafft. Am Montag haben wir uns die Zeit genommen und uns Salt & Pepper im Authentifizierungsumfeld angesehen. Mit Hilfe einer Demo-App haben wir von der Eingabe eines Benutzers mit Passwort über die Registrierung bis hin zum Login den gesamten Prozess geprototypt. Es war interessant und lehrreich. Weitere Demo-Apps sind in der Pipeline. Bspw. wie Digitale Signatur und arbeiten mit Zertifikaten funktioniert.
Die restliche Zeit haben wir an unserem Achievement-Details Screen gefeilt. Unserer Meinung nach gehört zu Motivation auch etwas Druck. Deshalb haben wir unser Achievement – zukünftig Challenge – geupgradet. Achievements können nun terminiert sein und müssen innerhalb eines festgelegten Zeitraums erledigt werden.
Zur visuellen Unterscheidung zwischen abgeschlossenen Achievements und zeitlich begrenzten Achievements können wir zwischen einem CalendarFragment und CountdownFragment wählen. Wer sich die App noch nicht installiert hat, kann die neuen Fragments einmal hier:
2021-05-04 Die Tage von AppAuth sind gezählt
Diese Woche haben wir uns teilweise darin versucht AppAuth abzulösen. Nachdem wir unsere Keycloak-Konfiguration letzte Woche auf „confidential“ umgestellt haben, haben wir uns diese Woche dazu entschieden, nicht weiter mit der AppAuth-Fehlermeldung zu kämpfen. Stattdessen haben wir uns näher mit dem Authentifizierungsprozess beschäftigt, mit dem Ziel, ihn besser zu verstehen und AppAuth letztendlich zu ersetzen. Anders als AppAuth haben wir bei der Authentifizierungsanfrage an unseren IdProvider keinen Browser geöffnet, sondern den Login in eine WebView eingebettet, was auf Anhieb funktioniert hat. Somit müssen wir die App nicht verlassen und können hoffentlich nach dem Login auch besser wieder zurück navigieren. Auch mit der Beschaffung des Authorization Codes haben wir nicht allzu lange verbracht und waren überrascht, wie weit wir an einem Tag gekommen sind.
Wir haben außerdem vom Client-Secret auf ein Zertifikat umgestellt, da man das Client-Secret pro Keycloak-Server nur generieren, aber nicht setzen kann. Dadurch müssten wir, wie wir es bisher mit dem JWT-Secret handhaben, im Coding nach dem Einchecken Änderungen vornehmen. Mit dem Zertifikat erhoffen wir uns, die Datei für mehrere Server verwenden zu können. Wir konnten allerdings bisher noch herausfinden, wie wir unseren Aufruf aufbauen müssen, da wir kein Beispiel finden können, wie und was gehashed werden muss, also haben wir es erstmal dabei belassen und wagen zu einem späteren Zeitpunkt nochmal einen Versuch.
Am Achievement-Detail-Dialog haben wir diese Woche auch noch einmal etwas gefeilt. Dadurch, dass wir den Close-Button und das untere Layout in ein zusätzliches Layout gewrappt haben, konnten wir jetzt auch einen Rahmen um den gesamten Details-Bereich ziehen, was ihn deutlich vom Hintergrund abhebt. Außerdem ist eine Deadline hinzugekommen, bis zu der man Zeit hat, das Achievement zu erreichen. Das soll die User etwas anspornen. So sieht er mittlerweile aus:
Zuletzt hat Peter uns in Miro, dem Brainstorming-Tool unserer Wahl, einen Bereich angelegt, in dem wir technische Begriffe sammeln, um uns über sie zu unterhalten und vielleicht dabei unser Wissensnetz langsam Stück für Stück zu erweitern.
2021-04-27 Bye bye, Mockito und Hallo, MVP-Planung
Nachdem wir uns vorletzte Woche damit beschäftigt haben, das Backlog aufzuräumen, haben wir es diese Woche wieder etwas gefüllt. Wir haben uns überlegt, welche Funktionalitäten unser MVP haben soll und uns dafür etwas Zeit genommen, damit jeder seine Überlegungen zu den bestehenden Screens und den noch fehlenden anstellen kann. Danach haben wir sie miteinander verglichen und nach MVP-würdig oder nettes-Feature-für-die-Zukunft unterteilt. Im Großen und Ganzen ist an Features nicht viel neues dazu gekommen, aber wir haben etwas unter den Wasserspiegel des Eisbergs geblickt und dort wartet noch jede Menge Arbeit auf uns. Eine größere Änderung, die ebenfalls noch in unser MVP einfließen wird, ist die Überarbeitung der Achievements. Peter hatte die Idee, unsere bisherigen Achievements in Challenges umzubenennen und erst nach erfolgreichem Abschluss der Challenge ein Achievement zu verleihen. So könnte es z.B. Daily-Challenges geben, die einen jeden Tag dazu animieren, etwas dazu beizutragen, um ein Achievement zu erhalten. Dieses Gamification-Prinzip, alles dafür zu tun, um bei der Daily-Challenge nicht auf 0 zurückzufallen, funktioniert sehr gut für Spiele, warum sollte es nicht auch in unserer App funktionieren?
Bye bye, Mockito: Mockito ist nun gänzlich verschwunden und wir haben es in allen Unittests durch Mockk ersetzt. Motiviert durch die einfachere Schreibweise haben wir gleich noch ein paar Unittests mehr geschrieben und sind jetzt immerhin bei 10% Unittestabdeckung. Kein Wert, auf den man generell stolz sein kann, aber für uns ist es ein guter Anfang und hoffentlich werden wir in Zukunft etwas mehr Zeit in die Tests investieren, damit es nicht weiter „ausartet“ und wir irgendwann überhaupt nicht mehr hinterher kommen.
Ein Vormittag ist nochmal in die Analyse unserer Keycloak-Logout-Thematik geflossen. Durch Änderungen an unserer Keycloak-Konfiguration haben wir den „introspect“-Endpunkt letztendlich aufrufen können, aber das zurück gelieferte Ergebnis war sowohl beim eingeloggten, als auch beim ausgeloggten User, das gleiche, womit wir an dieser Stelle nicht weiter kommen. Durch die Änderungen an der Konfiguration, bei der wir den Access Type von public auf confidental umgestellt haben, gibt es nun für unsere Zugriffe mit AppAuth wieder einmal Probleme. Zum x-ten Mal gibt AppAuth eine Fehlermeldung aus, mit der niemand außer der ursprüngliche Entwickler etwas anfangen kann. Unsere Überlegungen tendieren mittlerweile wieder dazu, uns selbst darum zu kümmern, auch um besser zu verstehen, wie die ganze Kommunikation/Verifikation funktioniert. Wir haben es mangels weiterer Ideen erstmal zurückgestellt. Oft muss man Dinge einfach mehrfach betrachten, bis man eine gute Lösung findet.
„Ausgelaugt von der Keycloak-Suche und erschlagen vom Backlog“ – nein, ganz so schlimm war es nicht 😛 – haben wir uns noch ein paar Quickwins gegönnt: Im User-Profil kann jetzt ein „About me“ ausgefüllt werden. Dabei ist uns der Bug aufgefallen, dass uns das E-Mail-Feld abhanden gekommen uns und wir haben es gleich behoben. Zu Testzwecken haben wir die ImageFactory auf einen Service umgestellt. Das Dashboard hatte eine kleine Schönheits-OP. Die Größe der Icons ist nun kleiner, da sich die Anzahl auf drei Spalten erhöht hat. Außerdem und wir haben uns entschieden, dass es schöner wäre, wenn die Kacheln mehr oder weniger gleich groß wären, weshalb wir uns erstmal dafür entschieden haben, die Länge eines Achievement-Titels einzuschränken.