JBoss get max post size - java

While I have managed to increase the max post size on my JBoss following
http://www.mastertheboss.com/web/jboss-web-server/configuring-wildfly-upload-file-size/
now I'd like my webapp to inform users. So I would like to render on the screen that the server accepts upload up to XXX MB.
How can a webapp retrieve the max post size setting from JBoss? Is there even a container agnostic way that could work across different servlet containers?

The max-post-size allows for an expression. That means you could use a system property which could be set on the attribute and retrieved by your application.
In CLI you'd do something like this:
/system-property=max.post.size:add(value=25485760)
/subsystem=undertow/server=default-server/http-listener=default/:write-attribute(name=max-post-size,value=${max.post.size:10485760})
While the default, :10485760, is not strictly required, I'd advise it.
Then in your application you simply just to simply retrieve the system property.

Related

Spring boot - Snowflake JDBC - Alter session automatically when application loads

I'm trying to connect Snowflake to Spring boot based application. Everything works well however due to some crazy defaults in snowflake, I'm having to deal with the below error:
https://community.snowflake.com/s/article/SAP-BW-Java-lang-NoClassDefFoundError-for-Apache-arrow
I can fire the queries via Spring data JPA but not able to map the results at all. The solution asks for changing the default resultset format from ARROW to JSON:
Customer can use this property (jdbc_query_result_format=json) in datasouce property of Application server or session property in application like
Statement = connection.createStatement();
Statement.executeQuery("ALTER SESSION SET JDBC_QUERY_RESULT_FORMAT='JSON'");
I'm just wondering how could I achieve that with Spring ie. run the above SQL in the bootstrap period. I'm using Spring data JPA queries.
The parameter JDBC_QUERY_RESULT_FORMAT can be set per account/user/session, therefore if you always want to have JSON for that user you can set it directly via Snowflake UI only once:
ALTER USER <youruser> SET JDBC_QUERY_RESULT_FORMAT='JSON';
This would only impact your user and the account would still have ARROW as default. And you wouldn't need to set it at session level all the time.
It turns out that the original issue can be fixed easily by tweaking some memory settings in your applications.
Summarising the solution below:
Increase the heap memory and setting -XX:MaxDirectMemorySize > 64M by setting the JAVA_OPTS property for your application.
The rationale behind this is that Arrow format inherently make use of the available heap memory in order to optimise the large results. Not having enough heap space will lead to the above mentioned error.
I still need to perform more tests to find out the ideal values for heap memory, stack size, and this variable → -XX:MaxDirectMemorySize.
EDIT: Below settings worked:
"JAVA_OPTS": "-Xss230k -XX:ReservedCodeCacheSize=100m -Xmx1800m -XX:MaxDirectMemorySize=1500m"
6 instances of the app running in parallel.
2GB RAM per instance ie. 12GB RAM in total (probably an overkill but it snowflake driver does eat up a lot of ram in general)

Switching app properties at runtime with app behind balancer

We have a Spring web app which is behind nginx balancer. A need occurred to change some properties at runtime, preferrably without redeployment/restart.
However, a simple in-memory way like a controller which changes the value doesn't solve the problem because the balancer will send it to one specific server and others will have old property value.
This property change feature is a tool for support team and is not expected to be used often.
We came up with next ideas:
Controller + field in the database which holds actual value. However, in this case we will need to always query the DB for actual value.
Controller + curl script + list of actual servers, not the balancer. Will do the job, but very error-prone in future.
Forget the idea and just redeploy the app changing the properties file manually.
Maybe there's something else?
No code is available yet, it's more like a design question.

Tomcat max connections on a per context basis

I have multiple web applications running under a single Tomcat container. Since they all run under a single Tomcat connector (as defined in the server.xml file), attributes such as maxConnections and maxThreads govern the container as a whole. As a result it is possible for a single application to consume all available Tomcat threads, starving the other applications of threads and making them unresponsive. I would like to be able to define the maximum http threads on a per context basis so that this is no longer possible.
Here's what I've tried so far:
Create a custom filter in the application that keeps track of the current thread count and limits additional connections. (Got the filter here: How to set limit to the number of concurrent request in servlet?). I'm not sure I like this solution, as it isn't as full-featured (support for attributes such as acceptCount, maxConnections, maxThreads, and minSpareThreads) as Tomcat provides by default to the container; and adding in the features feels like I am attempting to build what already exists in Tomcat.
Create a separate Tomcat connector in the server.xml file for each context. This has a few issues. For one, each connector requires a separate port; this means I'll have to account for this in my apache config. Secondly, I plan to add more webapps regularly; this means a config change followed by a tomcat restart, which is disruptive to clients.
Has anyone else encountered something like this? I feel like there should be a "Tomcat supported" workflow to accomplish what I'm after.
I'm going to post an answer that was provided to me from the Tomcat user group: http://tomcat.apache.org/tomcat-9.0-doc/config/valve.html#Semaphore_Valve (The Semaphore Valve is not Tomcat 9 specific, but was actually introduced in Tomcat 6). I experimented with this concept, and I found the following practical applications:
(Untested) The Semaphore Valve should be able to be nested within the Host element in the server.xml file.
(Tested) A [context-name].xml file can be placed inside [tomcat-home]/conf/Catalina/localhost with the valve nested within the Context element.
This is not necessarily the solution that I am going with, as more testing will need to be performed. However, I thought I'd add this as it is a potential answer to the problem.
Update:
As a recap, the SemaphoreValve was an option that was recommended to me through the Tomcat user mailing list as a solution to the issue that I described above. It turns out it was easier to implement than I anticipated. Adding the following to context.xml in the Tomcat/conf directory did the trick:
<Valve className="org.apache.catalina.valves.SemaphoreValve"
concurrency="10"
fairness="true" />
Thanks to Mark Thomas from the Apache group for supplying the solution.

How can a Tomcat webapp access its "maxthreads" parameter?

Our application accepts incoming requests (REST) and satisfies them using another of our services. When this application boots, it requests a number of connections from that other service - our goal is to maintain a 1:1, thread-to-connection, ratio (I won't get into why, its just that way).
Naturally, we want to define the number of threads/connections in one place, my thought is for the webapp to discover the "maxthreads" value as configured in server.xml -- without having to navigate to and parse the server.xml file. Is this possible?
Thanks
I'll answer my own question - JMX / MBeans.

How to get connection pool size programmatically in JBoss?

Is there any way to determine database connection pool size. I want to find out min pool size, max pool size.
The reason is as follows:
My application is running on Wildfly-9.0.1.Final.
I have configure datasource in -ds.xml file.
I have so many clients and for each one there is -ds.xml file.
In each file I have specified max-pool-size = 30.
But for some clients this size(30) happens to be small as more and more user tries to get connection from pool concurrently. Then in that case I need to increase max-pool-size to higher number. I want something like that will help me to fetch these parameters and then based on that I will perform some logic. Like if pool-size have reached to 25/30 then it will trigger email as an alert so that developer can increase its pool size. This way it will be helpful to avoid problems that client do faces when he could not get connection when all are being aquired.
Is there any way to access these connection pool parameters programatically.
Well there are multiple ways. If your datasource would be configured in the standalone.xml you could easily achieve your goal
via the CLI command (have a look here if you're not familiar with the CLI)
/subsystem=datasources/data-source=ExampleDS/statistics=pool:read-resource(include-runtime=true)
through JMX
by reading the following MBean
jboss.as:subsystem=datasources,data-source=ExampleDS,statistics=pool
Beware: In both cases ExampleDS has to be replaced with your actual datasource name.
Update
If you directly drop a -ds.xml into the deployments directory you can read the statistics like this:
/deployment=my-ds.xml/subsystem=datasources/data-source=java\:jboss\/my\/jndiName\/for\/DeployedDS/statistics=pool:read-resource(include-runtime=true)
or
jboss.as:deployment=my-ds.xml,subsystem=datasources,data-source="java:jboss/my/jndiName/for/DeployedDS",statistics=pool
Note that in any case you will have to enable these statistics first before you can acces any useful information with the methods shown above. These statistics might be a performance drawback. You can enable these statistics for example via CLI:
/deployment=my-ds.xml/subsystem=datasources/data-source=java\:jboss\/my\/jndiName\/for\/DeployedDS/statistics=pool:write-attribute(name=statistics-enabled, value=true)
When working with WildFly I'd generally recommend to configure datasources in the standalone.xml - it's way better supported.
Please try this with jboss-cli:
[standalone#localhost:9999 /]
/subsystem=datasources/data-source=ExampleDS/statistics=pool:read-resource(include-runtime=true)

Categories