jrule
jrule copied to clipboard
Feature collab: make generated JRule jars a remote repo?
Howdy!
First - thanks for taking on this project. It's way way way easier to build rules in an IDE and use external dependencies- this is awesome.
I had a thought about enhancing the way in which jrule vends the jars (and maybe even the way rules are uploaded) - would you be open to me taking a stab at having JRule spin up maven repo that holds the jars and potentially allows users to upload jars as well?
Basically my goal would be to point gradle / maven at my OpenHAB instance - where it could pick up the rule jars and in some crazy future - we could also publish the assembled rule jars there too.
It could also be useful for versioning rules and things - you tell JRule what version of the published jar to use.
I'm open to giving this a shot - so not asking you to do any more work - but wanted your thoughts first.
Thanks again!
Just spitballing - but maybe something like a dependency on reposilite? Might be an easy win (though, I'm certain there are other options)
Java developers will often have their own existing infrastructure set up for their projects. Every developer will have their own preferred development and deployment stack and these will differ from one person to the next. For example I use Reposilite, Laminar, Gitolite, Traefik, Let's Encrypt, Bacula, Darkhttpd (Arch Linux output packages), WireGuard, UFW, Ansible etc.
Irrespective of whichever infrastructure is used, there is an initial and ongoing cost to achieving secure, reliable and consistent integration. Nevertheless such costs are worthwhile when amortised over all available projects. It would therefore be desirable in the case of JRule for any existing infrastructure to be usable.
I do not have any particular view on how to use existing infrastructure other than suggest the simplest thing that could possibly work would be to define some simple contracts around the existing input and output JARs. For example if JRule detects a file system change at /etc/automation/jrule/rules-jar/
it would immediately undeploy any removed JAR and/or redeploy any modified JAR. Similarly JRule would guarantee to never rewrite the jrule-items.jar
unless there has been an actual change to the available items. The latter would allow a systemd timer (or a long-running script using inotify-tools
or similar) to detect a new version and upload it somewhere using whatever GAV coordinates make sense.
The benefit of this would be minimal changes within JRule while still allowing it to "play nicely" with external infrastructure. It would also fail gracefully, in that if the build infrastructure is unavailable the JARs already in openHAB would continue to operate. Fault tolerance is a major priority for home automation (especially for people who have replaced all their light switches with PoE wall tablets!)
Nice to see the interest in this. Already today there are mechanisms in place for detecting changes to rules or items and the reload JRule. I would be fairly simple to extend that to include the external jars as well, so whenever an external jar is changed (removed, modified, added) it would reload jrule.
If you have a way to publish jars I think it is fine and we could make changes to JRule to be more "compatible" in that sense. We could also set up reference projects that utilize for instance reposilite to publish and maintain the jar (similar to the https://github.com/seaside1/jrule-user ). I agree with @benalexau to support any type of infrastructure to handle versioning and release and dependencies to jar-files.
Thanks for the feedback.
My goal was to make the process of fetching the generated jar a bit more idiomatic. I agree, it probably doesn't make sense in some regard the "publishing" of the user rules jar and dependencies - those mechanisms are likely left best as is.
Taking into account the above comments - would it be a useful feature if we made the generated jar accessible via some sort of maven compatible repo? And we leave the publishing alone for now? (It doesn't have to be reposilite - anything that's able to be used as a repo source would do just fine)
Personally I wouldn't use that feature. The generated jar is not worth storing in that sense for me. It can be regenerated easily and I tend to share it by samba or nfs shared drive. The JRule.jar can be added as a dependency using maven and jitpack (See the jrule-user project as a reference).
would be fairly simple to extend that to include the external jars as well, so whenever an external jar is changed (removed, modified, added) it would reload jrule.
This would be useful as there's a precedent in the form of the .java
rule files, and supporting this for compiled JARs would allow people to push the replacement rules JARs into openHAB from whatever build automation they use.
The generated jar is not worth storing in that sense for me. It can be regenerated easily and I tend to share it by samba or nfs shared drive.
I agree; there are plenty of ways to get the generated JARs into user projects. The main issue is knowing that the JARs have meaningfully changed and in turn need to be updated in user projects. Simply preventing JRule from rewriting the JARs unless it detects the source content is now different is the most minimal change (eg you could CRC the entire source code stream as code generation progresses and include an entry in the generated manifest for comparison with a future run, thereby not needing any external persistence).
would it be a useful feature if we made the generated jar accessible via some sort of maven compatible repo? And we leave the publishing alone for now?
If generated JARs were only written when their contents changed you would be able to write an external script that basically fetched the existing 1.0.0-SNAPSHOT from your existing Reposilite instance, did a SHA on the fetched items JAR, did a SHA on the current JRule-generated items JAR, and pushed the new items JAR to Reposilite with a 1.0.0-SNAPSHOT version number if they differed. Then your usual infrastructure will pick up the new snapshot on developer machines, CI pipelines and so on.
The script could also fetch 1.0.0-SNAPSHOT of your rules JAR from Reposilite, and if its SHA differed from the current JAR in JRule, overwrite the current rule JAR to trigger JRule to automatically redeploy.
This approach would also be compatible with other mainstream approaches that people probably use, such as Samba shares, FTP or HTTP servers to expose JARs etc. It really just boils down to JRules (a) redeploying the rules JAR if it changes and (b) only rewriting the generated JARs if their source contents have changed. These are pretty minimal changes as far as I can tell and the behaviour of JRule wouldn't be unusual or unpredictable from a user perspective.
Some good suggestions.
- Yes would be fairly simple to check the external jars and to a reload when they are changed
- It would be possible to store a file along side the jrule-items and jrule.jar with checksums or store it in memory to avoid writing the same file multiple times.
Even though it is not a good solution I used to store the jrule-items and jrule.jar in version control and doing that the file will only show as changed / modified if it is actually changed.