Pages

Tuesday, July 31, 2012

Spring - Making a self configurable project

In my projects I prefer having self configurable solutions and avoid any additional involvement for deploying an enterprise application (EAR file).  For example, if the project needs to call some web services but the host address depends of the environment where the deploying is occurring (i.e. DEV, QAT, UAT, PROD).  Or you might need specific settings in each environment like DEV where you want to have more traces and debug information.  Imagine having to configure each setting every time you deploy...  plus this is prone to errors.


So how to make the solution self configurable?

In my case I use a combination of the JAVA env variable and Spring.

Set ENV Variable

Configure the JVM which hosts your application and set the vm argument:  -Denv <name>.

For example if using Geronimo application server, I will set this in the Launch Configuration where the VM arguments are configured.

-javaagent:"$(GERONIMO_HOME)/lib/agent/transformer.jar" -Djava.ext.dirs="$(GERONIMO_HOME)/lib/ext;$(JRE_HOME)/lib/ext" -Djava.endorsed.dirs="$(GERONIMO_HOME)/lib/endorsed;$(JRE_HOME)/lib/endorsed" -Xms512m -Xmx1024m -XX:MaxPermSize=512m -Dorg.apache.geronimo.home.dir="$(GERONIMO_HOME)" -Dkaraf.home="$(GERONIMO_HOME)" -Dkaraf.base="$(GERONIMO_HOME)" -Djava.util.logging.config.file="$(GERONIMO_HOME)/etc/java.util.logging.properties" -Dkaraf.startLocalConsole=false -Dkaraf.startRemoteShell=false -Denv=dev

Spring - ENV Configuration

I use Spring Framework to handle many of the dynamic characteristics of the project.  With Spring I can read the JVM env variable and do the following inside the applicationContext.xml file to achieve a self-configurable solution.

Spring - ApplicationContext.xml

This file is used by Spring to configure the application being loaded.  In the configuration I list two files:  application.properties and application.${env}.properties.  Notice the property files are bundle in the compiled JAR, so they are not easily visible nor accessible.  Plus you don't have to worry about the physical path since the files will be in the classpath.  The reason for having two files is that I can use one for all the general properties and another for environment specific settings.  Be careful that the order of the property files is important in the applicationContext.xml for how values are overridden.


    
    classpath:com/jonnazario/myapp/properties/application.properties
    classpath:com/jonnazario/myapp/properties/application.${env}.properties
    






    
    
    

For my preference I have a SystemProperties class which I load with values that are important for the application (i.e. Version, DevModeEnabled, HostName). For this I pass the property values as arguments to the constructor and if they are not defined in the property files, I still set the default values within the applicationContext.xml file.

Properties file

These are example values for the general and environment specific application properties files.  See how some properties are overridden while other are not defined at all.

Configuration - General
# -- General Properties
app.Version=2012.07.01.00
app.devModeEnabled=false

Configuration - DEV
# -- DEV Properties
app.Version=work.in.progress
app.devModeEnabled=true

Configuration - PROD
# -- PROD Properties
app.hostname=www.myapp.com


Hope this helps.

Wednesday, July 11, 2012

Android WebTop - CarPc Setup

For a while I have been working on integrating my phone into the car.  I thought about doing a full CarPC project like the ones in mp3car.com, but the reality is that I am cheap plus I want something "maintenance" free.  Well really.. what project is maintenance free?....  :)

The easy route to accomplish my goal was to use my aftermarket head unit display (Avic Z110BT) mixed with Motorola Atrix Webtop.  When I connect my "rooted phone" to the HDMI, the Webtop application takes over and I can see the Android screen in the head unit and the phone becomes a mouse and keyboard.  This allows me to take advantage of the Android applications like:  Google Maps, Pandora, Trapster, etc..  For aid, I use Vilingo to read text messages and voice commands.  Another future I like a lot is remote desktop to my in car notebook for running car diagnostics.

Too much talk...  Let me just show it and ask.  :)

Connection:


In this clip I show how the connection occurs between the Android WebTop and the the car's console.  For this project you need a head unit with video / audio input, hdmi to rca converter, power supply for phone and converter, phone mount.

Apps:



In this clip I show a basic idea of the apps. Something I missed recording is the usage of Vilingo for aiding in the hands free solution.  Also Vilingo developers.. please make the activation voice command to be always listening for "Hey! Vilingo" instead of only when app is open....


Car Monitoring:

In this clip I show how I monitor my car from within my phone.  I have a separate notebook computer which boots when car is on and hibernates when car shuts down.  From the phone I use WiFi AdHoc tethering so the PC and the phone can communicate wireless and I can remote desktop in.  The program shown is RossTech Vag-Com which is an OBDII monitoring tool for Audi.

My Car:  (Love Audi!)




Major progress:
  • Fix resolution of the rendered screen by updating Webtop X11 config
  • Hardwire the notebook computer used for monitoring the car
  • Setup tethering between notebook and phone (automatic)
  • Setup remote desktop and aspect ratio to be manageable from phone
  • Configure the remote Windows machine to have bigger icons, fonts, etc...



TODO:
  • Automatize the expansion of Android screen in head unit upon Webtop connection
  • Use something like Tasker which starts / stops Android apps upon detecting head unit bluetooth (just for knowing I am in car and is ON)
  • Better hands-free automation

Sunday, July 1, 2012

BIRT 3.7 - Dynamic connection profiles

The other day I used BIRT 3.7 Report Engine Runtime for generating reports over the web.  The reports creation and access will occur from different clients using technologies like .Net, JAVA, etc...  And the report design will use web services as the data source for populating the report information (data, images, etc..).

Something I had a little trouble when making the dynamic report was how to specify the data source connections dynamically?  In my case the solution is self-configure through having an environment variable which identifies the system as DEV, QAT, UAT, PROD.  All the different projects could be built one time and deploy to different environment without any configuration change.  I wanted the same for the reporting solution.

The ideas I read for making dynamic connections required to:
  1. Define the connection profiles pointing to the data sources
  2. Pass the connection profile name in the URL
This solves most of my problems, except when I found out that refreshing the web service WSDL schema will failed due to not knowing the connection profile to use.  For this I made a simple scripts which always defaults to the development connection and overrides when the connection profile parameter is passed in.
var profName = "DEV-Localhost.conn";

try { 
    profName = params["connProfileName"]; 
} 
catch (err) 
{  /* continue... */ }

reportContext.getAppContext().get("birt.viewer.resource.path") 
    + "/report/config/" + profName;


Putting it all together...

  1. Create the dynamic web project to host the BIRT report engine runtime.  In my setup I have "birt.viewer.resource.path" pointing to the WebContent folder.  So I just need to point the report designers in <path>/report/design/ and the connection profiles in  <path>/report/config/
  2. Define a connection profile for the data source.
  3. Define a report parameter for the connection profile name.
  4. Duplicate the profile connection file and edit the URI address to the data source.
  5. Dev-Localhost.conn
    
        
        
            
        
        
    
    

  6. Go back to the data source and add  in the property binding section the connection profile store script from above.
  7. Test the report by passing as an argument the different connection profiles in the report generation URL.
http://localhost:8080/WR/frameset?connProfileName=DEV-Localhost.conn&__report=report/design/MyReport.rptdesign
http://localhost:8080/WR/frameset?connProfileName=QAT-Server.conn&__report=report/design/MyReport.rptdesign
http://localhost:8080/WR/frameset?connProfileName=ETC-Server.conn&__report=report/design/MyReport.rptdesign