GlassFish 3.1.2 + Cluster + Web Container Properties - scala

I have an issue in Glassfish regarding dealing with properties wehn setting up a web application We are moving from using Jetty to a clustered environment setup with GlassFish on Amazon AWS
Conventionally speaking when dealing with Servlets you are meant to use a .properties file when you want to parse in environment variables, however this causes issues when you use a distributed environment (you would have to place the .properties file in every cluster node). GlassFish has the ability to configure properties of the web container through their Admin Console, which means the properties would automatically distribute through the cluster
The problem is, I am getting random behavior regarding retrieving the variables. The first time I ran a test application, I couldn't retrieve the variables, however no it no longer works
Basically I am setting the environment variables through the admin UI. Under Configurations there are 3 configuration stetings, one for the cluster (usually named .config), one default-config and one server-config. Under Web Container, I have put a test property in all 3 of the called "someVal".
I then created a quick Scalatra app in Scala (which uses Servlet 2.5) and I used this line to attempt to get the properties
getServletContext.getInitParameter("someVal")
Any ideas what I am doing incorrectly, it always returns null?
Update
It appears what I was attempting to do isn't the "correct" way of doing things. So my question is, what is the standard way of providing specific application settings (outside of the .war and outside of runtime) when dealing with clusters in GlassFish. myfear stated that using a database is the standard approach, however I use these configuration settings themselves to define the JDBC connection

I got it. You are referring to the Web Container Settings
http://docs.oracle.com/cd/E18930_01/html/821-2431/abedw.html
I'm afraid that this never has been thought of as providing application specific configuration and I strongly believe that you will never be able to access those properties from the servlet context.
So, you could (should) use the servlet init params in web.xml if you are talking about application specific information. if you use
getServletContext().setInitParameter("param", "value");
you might be able to set them (at least for the runtime of the application). I'm not sure about cluster replication here. The normal way would be to have you configuration settings in the database.

Related

Temporarily disabling default services in servicefabric using powershell

The concrete question
For those who just want the direct questions:
Is there a way to temporarily disable default services on a ServiceFabric application type so that a new application can be installed (using Powershell) without automatically installing any default services?
A proposed solution here is to remove the default services from the manifest and later restoring them. I am able to write a PowerShell script to adjust the application manifest accordingly, but how do I update the application type using Powershell - assuming I already have altered the manifest?
Any solution that solves the contextual problem without requiring manual config meddling is acceptable - my proposed solution is probably not the only possible solution. We do explicitly want to avoid manual meddling.
When allowing meddling, we are already able to just comment out the default services when we need to. We're specifically looking for a solution that requires no meddling as this reduces bugs and debugging issues.
The context
I'm running into an issue with using the application manifest's default services during local development.
I am aware of the general "don't use default services" advice, and it is being followed. During CI build, the default services are removed and will not be relied upon for any of our clusters in Azure. The only exception here is local developer machines, which use default services to keep the developer F5 experience nicer by enabling all services when starting a debug session.
We have written specialized scripts that provision a new tenant (SF application) with their own set of services (SF service). Not every tenant should get every service, we want to opt-in to the services, which is what the script already does (based on a mapping that we manage elsewhere, which is not part of the current question as the provisioning script exists and works).
However, when default services are enabled, every tenant already gets every service and the actual opt-in provisioning is useless. This is the issue we're trying to fix.
This same script works in our production cluster since there are no default services configured there. The question is solely focus on the local development environment.
Essentially, we're dealing with two scenarios during local development:
When debugging, we want the default services to be on because it allows us to run all of our services by pressing F5 (and not requiring any further action)
When testing our provisioning script, we don't want default services because it gets in the way of our selective provisioning behavior
I'm aware that commenting the default services out of the manifest solves the issue, but this requires developers constantly toggling the content of the manifest and reinstalling the application type, which we'd like to avoid.
Ideally, we want to have the default services in the manifest (as is currently the case) but then have the provisioning script "disable" the default services for its own runtime (and restore the default services before exiting), as this gets us the desired behavior in both cases.
What is the solution that requires the least manual developer meddling to get the desired behavior in both scenarios?
I'm currently trying to implement it so that the provisioning script:
Copies the application manifest to a backup location
Removes the default services from the real manifest
Updates the application type using the new manifest (i.e. without default services)
Runs the provisioning logic
Restores the real manifest using the backup manifest from step 1
Updates the application type using the restored manifest (i.e. with default services)
It is specifically steps 3 and 6 that I do not know how to implement.
Consider having two sfproj projects in the solution. One with default services, one without.
Also look into using a start-service.ps1 script instead of default services. This way the two projects can use the same application manifest.
https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-debugging-your-application#running-a-script-as-part-of-debugging

Is it possible to modify the test server configuration in each separate microservice project?

I am developing a number of microservices which will run on Open Liberty. I have set up a test server in my eclipse environment which is configured to use all the features required by all the services which I am currently working on.
Whilst this works, it seems a heavy-handed approach and it would be good to test each service in an environment which closely resembles the target server. The services can differ in the set of features they require as well as the JVM settings necessary.
Each service will run in its own docker container and the docker configuration is defined in each project.
Is there a way to better test these services without explicitly setting up a new server for each individual service?
I am not aware of any way to segment the Liberty runtime (its features) nor the jvm (for different jvm settings) for different applications running in a single Liberty instance.
You can set app specific variables and retrieve them using MP Config, but that's not the same as jvm settings and certainly not the same as trying to segment specific features of the runtime to a specific application.
However, in general when testing, I would highly recommend trying to mimic your production environment as much as possible. Since you're planning on deploying into docker, I would do the same locally when testing, and given Liberty's lightweight, composable nature, it's unlikely that you'll hit resource issues locally when doing this (you should only enable the features on each Liberty instance that your app is using to minimize the size of that instance). This approach is one of the big benefits/value provided by containers and Liberty.
In other words, even if you could have one Liberty instance segmented per application, I would not recommend it for your testing because, as you said, "it would be good to test each service in an environment which closely resembles the target server"

How do I see what a JBoss deployment uses?

In a JBoss environment (specifically EAP 6) with several JARs deployed, several data sources, a lot of system properties, etc. How can I find what a particular JAR users?
For example, is there anyway I can see that "deployment-1.jar" uses "datasource-1" "system-property-2" and "system-property-5"?
What about the reverse? Eg finding out which deployments use a particular datasource?
Note: I'm looking at this from the perspective of an App Admin, maintaining a production system without necessarily having access to the source code.

Building two different versions a given war with maven profiles and filtering from eclipse

I am trying to use maven profiles and filtering in order to produce two different versions of a given web archive (war):
A first one for local deployment to my local machine on localhost
A second one for remote deployment to cloudfoundry
There are a number of properties that differ according to whether the app is deployed to my local machine or to cloudfoundry.
Of course the difficult bit is that I am trying to do all this from STS/Eclipse and deploy from Eclipse to my local tomcat and to cloudfoundry...
Can anyone please provide advice, tips or suggestions?
If you are using Spring versioning 3.1+ the "profile" attribute for <beans> in the spring bean configuration xml would be the best choice. Take a look at the doc here: http://docs.cloudfoundry.com/frameworks/java/spring/spring.html#using-spring-profiles-to-conditionalize-cloud-foundry-configuration
Basically you need to specify at least 2 elements. One for your local properties (profile="default") and one for the properties when deployed to CF. The latter one should be defined as <beans profile="cloud">. When running locally the properties within "cloud" would be ignored and properties in "default" will take effect. When pushed to CF, CF will detect the profile named "cloud" and, which is better, inject corresponding datasource connection info of the services provisioned by CF itself. You can find the detailed CF-specified properties in that doc as well.
For more information about the profile attribute, see the doc here: http://blog.springsource.com/2011/02/11/spring-framework-3-1-m1-released/
Consider having a single project per artifact generated. Hence one project generating your local deployment and one project generating your cloudfoundry deployment.
Overlays (http://maven.apache.org/plugins/maven-war-plugin/overlays.html) is the officially sanctioned way to bake in extra files in an existing WAR file, giving a new WAR artifact. Very useful but may be too slow for comfort while developing.

startup class (extends ServiceMBean) vs load-on-startup servlet

I am new to jboss and would like to know what are the differences between ServiceMBean and load-on-startup servlet tag in web.xml? Also, I would like to know which one will always get loaded first or they are loaded at the same time? In what situation, I should use MBean and when I should use startup servlet or it doesn't matter?
I need to write a a class/servlet to validate if all the required system properties (e.g -DINSTALL_DIR=blah ) is set. If not, then stop right there. else proceed and start the application.
Thanks in advance
-A
ServiceMBean is JMX, it is part of your JVM. load-on-startup servlet tag in web.xml is part of your J2EE application.
JMX is part of J2SE starting from JDK 1.5. So, you can have one ServiceMBean per JVM. not per application. JMX is used mostely for monitoring and managing the JVM. It provides access to information such as: number of classes loaded and threads running, memory consumption, garbage collection statistics, on-demand deadlock detection, and others. Another common use, is to refresh your cache.
JMX will allow you to instrument your application and control/monitor it using what-ever management console that your JMX container supports. An example would be a web application that implements a reference data cache...
A problem we had before was we would occasionally need to refresh the cache because a customer name changed in the database. If we had a refresh method on the MBean interface then we should be able to trigger this event using the JMX console. The JMX console may be a web or fat client that comes with our J2EE server. Our J2EE server may also support SNMP. This means that we may be able to invoke the method from a standard Tivoli or UniCenter console.
http://www.theserverside.com/news/1364664/J2EE-Application-Management-The-Power-of-JMX
You don't need remote access to ServiceMBean in order to trigger some asynchrious action. Moreover, you need validation on scope of application, not the whole JVM (while, you can, theoretically, handle this issue in the ServiceMBean). So, it is more naturally, to do it as load-on-startup servlet tag in web.xml. In this way, in every start up of your application validation will happen.
One more clarification: ServiceMBean is JBoss-way to write JMX. All MBeans are server wide (not application wide). That's why I use MBean and ServiceMBean freely above.