Development Guide

Quickstart
-
Build Isis with kroviz
cd ~/isis mvn -T 1C clean install \ -Dmodule-kroviz \ -Dmaven.source.skip=true
-
Start kroviz
cd ~/isis/incubator/clients/kroviz/ #gradle build ./gradlew.sh -t run
-
Start the Server App
-
Enter in the Browser:
http://localhost:3000
-
Select 'Connect' in the Burger Menu
Originally Apache Isis SimpleApp 1.16.0 was used as the reference RO backend. This required some extra steps in order to deal with CORS setup, see sections on pre 2.0.0-M3 and CORS. Currently (2.0.0-M6) Demo is used as reference - at the moment it’s the only CORS enabled application. === Frontend |
Requirements
Kotlin/JS uses Gradle
for the build, for the JS runtime NodeJS
, and for the JS dependency management part npm
.
You should have installed:
* node js (https://nodejs.org/en/download/current/)
* Apache Gradle
* Google Chrome (72.0.3626.81 or higher)
* <Moesif CORS Plugin (for Chrome)
Build
gradle can be run under Windows with git-bash:
-
./gradlew.bat tasks # list all gradle tasks
-
./gradlew.bat webpack-bundle # create main.bundle.js
-
./gradlew.bat test –exclude-task npm-install
Internally gradle uses npm for the JS part.
In IntelliJ import the gradle project residing in ~/isis/incubator/clients/kroviz/. TIP: In case the project isn’t working as expected, you may try File → Invalidate Caches … Alternatively you can e.g. in IntelliJ a Run/Debug Configuration:

npm --verbose
If task npm-install hangs, try
./gradlew.bat npm-install --info --debug --stacktrace
Helps in identifying thing that may go wrong (e.g. due to proxy settings).
Design
In the following section you’ll find information that likely helps understanding the implementation.
Patterns Applied
Redux
The implementation is an (independent) reinvention of Redux. I prefer the name Aggregator over Reducer though - IIRC Aggregator is prior art.
Half Object Protocol
The HOP pattern dates back to the early 2000, namely CanooULC. IMO Naked Objects together with the RO API and kroViz resembles something similar.
Event Sourcing (EAA)
Requests, reponses, and resulting TO’s are logged. Before requests are sent out to the server this log is consulted and used as a cache.
Aggregator (EAI)
Various aggregators are responsible to collect or assemble displayable objects. Once all layout information is there, the UI will be rendered, even if not all elements of a list have arrived. Those elements will be added as they arrive. This is done with the help of mutable lists.
Chain of Responsibility (GOF)
A chain of handlers is used to identify what kind of TO is to be generated from the JSON response. Handlers are responsible for initial assignment of aggregators.
Code
Thanks to Kotlin, code is very compact and readable. And, since Kotlin is a typed language and IDE’s can infer a lot about the code, there are only few surprises. Nevertheless Kotlin/JS allows to use JavaScript features alongside the typed part, what effectively makes it a dynamic language.
Trouble Shooting
Corporate Firewall with SSL 'inspection'
There are some questionable setups in coporate settings that are based on SSL replacement. In order to cope with it, you may try to import the Certificate into cacerts, see https://intellij-support.jetbrains.com/hc/en-us/community/posts/115000094584-IDEA-Ultimate-2016-3-4-throwing-unable-to-find-valid-certification-path-to-requested-target-when-trying-to-refresh-gradle
Network Proxy
Depending on the network you are in, you may need to configure the proxy settings. Among the relevant files are: `bash ~/.npmrc ~/.gitconfig ~/.ssh/config ~/.ssh/id_rsa ` ### References * https://jjasonclark.com/how-to-setup-node-behind-web-proxy/ * https://gist.github.com/EudesSilva/0329645b9c258e0495544b8a5ccd1454
Access to git from npm
Problem
npm ERR! Error while executing:
npm ERR! C:\Program Files\Git\bin\git.EXE ls-remote -h -t ssh://git@github.com/jarecsni/font-awesome-webpack.git
npm ERR!
npm ERR! git@ssh.github.com: Permission denied (publickey).
npm ERR! fatal: Could not read from remote repository.
npm ERR!
npm ERR! Please make sure you have the correct access rights
npm ERR! and the repository exists.
npm ERR!
npm ERR! exited with error code: 128
Solution
ProxyCommand /bin/connect.exe -H proxy.server.name:3128 %h %p
Host github.com
User git
Port 22
Hostname github.com
IdentityFile "C:\users\username.ssh\id_rsa"
TCPKeepAlive yes
IdentitiesOnly yes
Host ssh.github.com
User git
Port 443
Hostname ssh.github.com
IdentityFile "C:\users\username.ssh\id_rsa"
TCPKeepAlive yes
IdentitiesOnly yes
Misc
Toolchain Overview
When you are accustomed to the well settled Java ecosystem with integrated development environments, prepare yourself for learning new tools and addressing new problems.
Kotlin is straightforward and once you know it, you may not want to go back.
-
JSON structures can be visualized via kroki (cf. History → Details)
-
Layout: for FLEX see https://css-tricks.com/snippets/css/a-guide-to-flexbox/
The Browser as Client Runtime Environment
Google Chrome is used as browser. It has a very feature rich debugger (<CTRL>-<SHIFT>-I) which can even be connected to IntelliJ’s debugger (Settings → Preferences → Extension → Link handling). For a nice introduction to Chrome, see: https://www.google.com/googlebooks/chrome/.
All current browsers implement some security features in order to counteract Cross-Site-Resource-Forgery (XSRF). CORS (Cross-Origin-Resource-Sharing) is beeing devised to allow access to resources from a different host-port under certain circumstances. It is said to be bypassable via https://www.npmjs.com/package/node-iframe, cf. https://stackoverflow.com/questions/33143776/ajax-request-refused-to-set-unsafe-header/66782595#66782595
Visualize JS dependencies
E.g. via https://npmgraph.js.org/
Build the Backend Yourself
Appendix
JSON Terminology
See: elp.kapowsoftware.com/9.4/index.jsp?topic=/doc/rm/JSONTerminology.html
JSON Text |
JSON Object | JSON Array |
JSON Object |
{} | { Properties } |
JSON Array |
[] | [ Items ] |
Properties |
Property, Properties |
Property |
String : JSON Value |
Items |
JSON Value, Items |
JSON Value |
JSON Text | String | Number | false | null | true |
String |
"" | " Characters " |
Characters |
|
Character Characters |
|
Character |
any Unicode character except ", \ or control character | " | \ | \/ | \b | \f | \n | \r | \t | \u 4 hex digits |
Number |
a number very much like a C or Java number, see RFC 4627 for details. |
CORS
CORS stands for 'Cross Origin Resource Sharing' aka: 'Same Origin Policy' was designed to improve security and is implemented in browsers. In short it means: your browser will allow loading of resources only if host and port are identical to the url you are on. Ie. webpage loaded from http://localhost:8088/ resources from http://localhost:8080/restful will not be accessible.
Solution 1 (Q&D):
Disable CORS in your browser, e.g. for Chrome with the MOESIF plugin.
Nicely done introduction:
Solution 2:
Add to webapp\src\main\webapp\WEB-INF\web.xml
<!-- CORS filter for XmlHttpRequests -->
<filter>
<filter-name>cross-origin</filter-name>
<filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
<init-param>
<param-name>allowedOrigins</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>allowedMethods</param-name>
<value>*</value>
</init-param>
<init-param>
<param-name>allowedHeaders</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>supportsCredentials</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>chainPreflight</param-name>
<param-value>false</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>cross-origin</filter-name>
<url-pattern>/restful/*</url-pattern>
</filter-mapping>
`
Put into webapp/src/main/webapp/WEB-INF/lib: * https://search.maven.org/artifact/org.eclipse.jetty/jetty-util/9.4.12.v20180830/jar * https://search.maven.org/artifact/org.eclipse.jetty/jetty-servlets/9.4.12.v20180830/jar
Extensions
OSM/Leaflet
-
2.5D, buildings see https://osmbuildings.org/documentation/leaflet/
-
Magnifying Glass
-
Wikipedia markers
-
Routing