Change http root-path of a quarkus application in runtime - quarkus

Is it possible to set the root-path of a Quarkus service in runtime?
When I set quarkus.http.root-path in runtime I see the following error:
[io.qua.run.ConfigChangeRecorder] (main) Build time property cannot be changed at runtime. quarkus.http.root-path was /{old-context-path} at build time and is now /{new-context-path}

Changing the root path of a running application is impossible, or at least hard to do. Using Vert.x, it would be possible but that requires some coordination since you would need to deploy/undeploy components (Verticles) in the runtime.
What you still can do: Start another instance (process) of your Quarkus application with the new root path (for example -Dquarkus.http.root-path=<newroot>), then shutdown the existing instance.
This will, however, make the old root path unavailable to all clients which rely on it.

Related

How to change Quarkus context path at startup

For a cloud native application written with Vert.x, I need to change the context path using an environment variable depending on where it is deployed. I tried with:
quarkus.http.root-path=${CONTEXT_PATH:/app}
in application.properties but it is not taken into account at runtime, just at build time. Here is also reported that this property is build time only. What's the way to change the context path then?

Which configuration properties are not changeable in deployment time / runtime in Quarkus?

I was reading the Quarkus documentation about configuration, and this caught my attention:
Quarkus does much of its configuration and bootstrap at build time. Most properties will then be read and set during the build time step. To change them, make sure to repackage your application.
Where can I find the list of configurations that are not changeable on deployment time/runtime?
All of the Quarkus configuration options can be found here:
https://quarkus.io/guides/all-config
To the left of some properties there is a "lock" icon, which means the configuration property is fixed at build time. All other properties that do not have the "lock" icon next to them may be overridden at runtime.
For example, the quarkus.datasource.jdbc.driver property is fixed at build time, meaning between dev/test/prod you must use the same JDBC driver. On the other hand, properties such as quarkus.datasource.jdbc.url may be overridden at runtime, so at dev/test time it could point to jdbc://localhost:5432/myDB and in production this value could point to the production DB URL.

Update for JavaEE application

Our application are built on Spring boot, the app will be packaged to a war file and ran with java -jar xx.war -Dspring.profile=xxx. Generally the latest war package will served by a static web server like nginx.
Now we want to know if we can add auto-update for the application.
I have googled, and people suggested to use the Application server which support hot deployment, however we use spring boot as shown above.
I have thought to start a new thread once my application started, then check update and download the latest package. But I have to terminate the current application to start the new one since they use the same port, and if close the current app, the update thread will be terminated too.
So how to you handle this problem?
In my opinion that should be managed by some higher order dev-ops level orchestration system not by either the app nor its container. The decision to replace an app should not be at the dev-ops level and not the app level
One major advantage of spring-boot is the inversion of the traditional application-web-container to web-app model. As such the web container is usually (and best practice with Spring boot) built within the app itself. Hence it is fully self contained and crucially immutable. It therefore should not be the role of the app-web-container/web-app to replace either part-of or all-of itself.
Of course you can do whatever you like but you might find that the solution is not easy because it is not convention to do it in this way.

Getting the upload folder in a Java servlet container

Could be a silly question, but...
I have a Spring-based WAR application that runs 80% of the installations on Tomcat and the rest 20% on WebSphere.
I need to simply get the path of the folder where Spring's MultipartFilter (using Commons multipart resolver) stores files being uploaded. I have never set it manually, and it actually belongs to the Catalina work directory as I found out in my Tomcat installations.
For the moment, I just need to get that path. I have control of my application so no one is going to change it without notice.
I would like to know if there is a server-agnostic way to know where my Spring-based application is going to store Multipart files.
E.g. from this question I can see I can use catalina.base, but in Tomcat... not in JBoss or WebSphere. It could cost me a couple of if/else statements...
Spring tries to do it already when no default value is set
WebUtils.getTempDir(servletContext)
Which simply does:
return ((File)servletContext.getAttribute("javax.servlet.context.tempdir"));
So simply if no one overrides that location in the filter properties (and that is my case) I can rely on the default.
More in general, one may have to inspect the instance of DiskItemFileFactory to get the path to the repository

Can I create a transient configuration in OSGi using the ConfigAdmin?

I'd like to create a Configuration object in OSGi, but one that won't be persisted, so it won't be there when the framework is restarted. Similar to START_TRANSIENT for bundles.
Some background: I've got an OSGi (Felix) based client side application, deployed over OBR. The configuration object I'm talking about effectively boots the application. That works fine, but sometimes the content has changed while the context was stopped. In that case, it boots the application as OSGi revives all bundles and adds all configuration options. Then I inject the correct configuration, the application stops and then restarts again.
So it does actually work, but the app starts twice, and I can't get access to the framework before it reconstructs its old state.
Any ideas?
As BJ said there is no standard support for this in the Configuration Admin spec.
However the Felix implementation supports two features which may help you. First, you can set the felix.cm.dir property which configures where the configadmin saves its internal state (which by default will be somewhere under the Framework storage directory). You could set this to a location that you control and then simply wipe it every time you start OSGi (you could also wipe out the entire OSGi Framework storage directory on every start... some people do this but it has wider consequences that what you asked for).
Second, if you need a bit more control, Felix ConfigAdmin supports customising its persistence with a PersistenceManager service. You could probably implement this and return empty/doesn't-exist for the particular pids that you want to control.
The OSGi Config Admin spec does not support this. I also do not know of a non-standard means either for any of the CM impls I am familiar with.
Ok, what I did in the end was the following:
I created a special really small 'boot' bundle, which I do not provision from OBR, instead, I install it from the classpath.
That bundle controls the configuration, and I use START_TRANSIENT the moment I really want to load that configuration.
Not exactly pretty, it gets the job done. I do think transient configuration would make sense to have in OSGi.

Resources