Wednesday, October 10, 2012

Sencha Ext JS Customer Spotlight: Incentrak

One of our last Ext JS and Spring enterprise projects is being featured on the Sencha website:

http://www.sencha.com/blog/customer-spotlight-incentrak/

Wednesday, August 1, 2012

Running Tomcat on HTTPS with a Secure Certificate on Dreamhost

From http://www.appfoundation.com/2012/08/running-tomcat-on-https-with-a-secure-certificate-on-dreamhost/:


1. Create a new domain
  • Login to your Dreamhost account
  • Go to "Manage Domains"
  • Select to "Add New Domain"
  • Make sure to specify the "Run this domain under the user" as a user associated with the FTP account on your private server. This results in the new domain being installed on your private server
  • Wait for the new domain to be active, which can take up to 15 minutes. Once you can hit the new domain in your browser you are ready to go.

2. Add SSL to the domain
  • Login to your Dreamhost account
  • Go to "Manage Domains"
  • Next to your domain press the "Add" button in the "Secure Hosting" column
  • Fill out the admin information for your domain
  • Wait for the SSL version of your domain to be available, which can take up to 15 minutes. Once you can hit the HTTPS version of your domain you are ready to go.
  • This service costs $5/month

3. Add a professionally signed secure certificate to the domain
  • This is required if you don't want your users to get the "Not a secure site" warning page when going to the HTTPS version of your site
  • Login to your Dreamhost account
  • Under "Domains" go to "Secure Hosting"
  • Select to "Add Secure Certificate"
  • Fill out the information and order the certificate
  • Wait up to 15 minutes for the certificate to be complete. Once the status of the certificate request on the "Secure Hosting" page is "OK" you are ready to go.
  • This service costs $15.00

4. Fix Dreamhost overwrites
  • The addition of this service will cause your private server to have some of its components refreshed, depending on what things you have selected to have managed on the Private Server dashboard
  • The most common issue is the refresh of the MySQL configuration file, in which the default version doesn't allow lower case table names
  • You know this is happening when you start getting database errors about table names not being found
  • Modify MySQL to not use case sensitive names, which means you have to edit /dh/mysql/mysql/my.cnf
  • Add lower_case_table_names=1 AFTER the [mysqld] tag. If you add this param before, it does not get picked up by the startup script.
## my.cnf for ds3241:mysql (generated)
#
# put local parameters in my.cnf.local for inclusion below
#
### useful info:
# socket = /dh/mysql/mysql/mysql.mysql.sock
# backup user = root
# backup pass = PASSWORD_HERE
[mysqld_safe]
open_files_limit = 65535
[mysqld]
# options without values
lower_case_table_names=1
log-warnings
new

5. Change Apache ports (if you are running Tomcat HTTP on 80 and Tomcat HTTPS on 443)
  • If you are running Tomcat on port 80 and intending on running HTTPS on 443, you will need to tell Apache to run somewhere else
  • You have to edit /usr/local/dh/apache2/httpd-argon/etc/httpd.conf and change all of the port :443's to :8443's

6. Restart the server
  • Login to your Dreamhost account
  • Go to "Dedicated Servers" and then "Dashboard"
  • Press the "Restart" button next to your private server
  • Wait for about 5 minutes for the server to come back up

7. Install tools needed for generating a certificate for Tomcat

8. Generate a keystore for Tomcat using your certificate
  • This took me a really long time to figure out. http://www.brandonchecketts.com/archives/convert-and-openssl-apache-ssl-certificate-to-a-pkcs12-tomcat contained the missing pieces.
  • In Dreamhost go to Secure Hosting and select the "View" button next to your Secure Certificate for your domain
  • This will show you 3 keys: Certificate, Private Key, and Intermediate Certificate
  • Copy and paste the Certificate into a file named "yourdomain.com.crt"
  • Copy and paste the Intermediate Certificate into a file named "yourdomain.com.int"
  • Copy and paste the Private Key into a fie named "yourdomain.com.key"
  • Run the following at the Windows Command Line:
openssl pkcs12 -export -in yourdomain.com.crt -out yourdomain.com.pkcs12 -name "yourdomain.com" -inkey yourdomain.com.key
  • Pick a password for the keystore, which you will need to put in the Tomcat server.xml in the future
  • This generates a file called yourdomain.com.pkcs12

9. Upload the keystore
  • Upload the yourdomain.com.pkcs12 to the conf directory of your Tomcat installation on your private server
  • For example our Tomcat conf directory is /opt/apache-tomcat-7.0.27/conf

10. Modify the Tomcat server.xml
  • First you have to set the redirect to the HTTP port from the perspective of the HTTPS port. Note that all you need here is the redirect port, everything else
is specific to an ExtJS GZIP optimization
Connector port="80" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="443"
compression = "on"
compressableMimeType="text/html,text/xml,text/css,text/javascript,application/x-javascript,image/jpeg,image/png,image/gif"
compressionMinSize="1"
  • Next you have to add a connector configuration for HTTPS that references the keystore:
Connector port="443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="conf/yourdomain.com.pkcs12" keystoreType= "PKCS12" keystorePass="YOUR_PASSWORD"
compression = "on"
compressableMimeType="text/html,text/xml,text/css,text/javascript,application/x-javascript,image/jpeg,image/png,image/gif"
compressionMinSize="1"

  • Finally you have to modify the AJP connector:
Connector port="8009" protocol="AJP/1.3" redirectPort="443" 

11. Startup your Tomcat instance
  • From the Tomcat directory run ./bin/startup.sh and make sure logs/catalina.out doesn't contain any errors related to the keystore
  • The HTTPS version of your site should now be running using your certificate, which means there won't be a security warning page when visiting the site

Thursday, July 5, 2012

Custom themes in Ext 4.1 not generating images through slicing



Custom theme slicing is not generating images in 4.1 as it did in 4.0.
In 4.0 assuming a directory structure like the following:
  • app - Contains the app source
  • extjs - Contains the Ext JS Framework
  • resources
    • css - Intended to contain generated css
    • images - Intended to contain generated images
    • sass
      • _myapp-buttons.scss
      • config.rb
      • my-ext-theme.scss
    • maniest.json - Specifies the custom components for which to generate images
  • app.js
Whenever you run the "compass compile" on the project, you get the expected css file generated in the css directory:
  • app
  • extjs
  • resources
    • css
      • my-ext-theme.css - The generated theme css
    • images
    • sass
      • _myapp-buttons.scss
      • config.rb
      • my-ext-theme.scss
    • maniest.json
  • app.js
If you look at my-ext-theme.css when using 4.0, you will see the following:
  • framework items are located at ../../extjs/resources/themes/images
  • custom theme items are located at ../images
If you look at my-ext-theme.css when using 4.1, you will see the following:
  • framework items are located at ../../extjs/resources/themes/images/default
  • custom theme items are located at ../images/default
So between 4.0 and 4.1 images moved from images to images/default
When you run the slicing tool on the project (ext-theme.exe on Windows) out of Sencha SDK Beta Tool 3 on 4.0 you get the following:
  • app
  • extjs
  • resources
    • css
      • my-ext-theme.css
    • images
      • btn
        • btn-custom-small.bg-gif
        • btn-custom-small-corners.gif
        • btn-custom-small-sides.gif
    • sass
      • _myapp-buttons.scss
      • config.rb
      • my-ext-theme.scss
    • maniest.json
  • app.js
When you run the slicing tool on the project  (ext-theme.exe on Windows) out of Sencha SDK Beta Tool 3 on 4.1 you get the following:
  • app
  • extjs
  • resources
    • css
      • my-ext-theme.css
    • images - Nothing is generated
    • sass
      • _myapp-buttons.scss
      • config.rb
      • my-ext-theme.scss
    • maniest.json
  • app.js
No images are generated. What happened?
After poking through the extjs framework directory for things like "default" and "images" nothing stood out. After having already spent quite a bit of time on this, and being on the last week of a particular project, I was left with a few choices:
  1. Fix something in the framework
  2. Ask around to find if someone else has an answer
  3. Implement a hack, and correct it later
So here is the hack:
  1. Compass compile the SCSS into CSS (doesn't involve the extjs directory)
  2. Slice the theme against the Ext 4.0 framework
  3. Copy directories from resources/images into resources/images/default
  4. Delete the directories that you copied out of resources/images
My Ant code looks like the following:



<target name="slice-theme-hack">
<!-- An ant macro around compass compile -->
<af-sencha-compile-sass-into-css
sencha-resources-dir="${basedir}/WebContent/resources"
/>
<!-- An ant macro around slicing themes -->
<af-sencha-slice-theme
sencha-extjs-dir="${basedir}/theme-hack/extjs-4.0"
sencha-resources-dir="${basedir}/WebContent/resources"
theme-css="my-ext-theme.css"
manifest-json="manifest.json"
/>
<copy todir="${basedir}/WebContent/resources/images/default">
<fileset dir="${basedir}/WebContent/resources/images/">
<exclude name="default/**">
<exclude name="*.*">
</exclude></exclude></fileset>
</copy>
<delete includeemptydirs="true">
<fileset dir="${basedir}/WebContent/resources/images/">
<exclude name="default/**">
<exclude name="*.*">
</exclude></exclude></fileset>
</delete>
</af-sencha-slice-theme
</af-sencha-compile-sass-into-css
</target>

Monday, June 25, 2012

Implementing Continuous Integration

Continuous Integration is something that is sometimes hard to make work for you, especially in existing environments. This is why I have laid out a process for helping to identify the basic infrastructure components needed for working with and getting value out of continuous integration. The benefits of using continuous integration are numerous, and ultimately result in a much faster delivery and turn-around time for software.

Full Details: http://www.appfoundation.com/ci/

Thursday, May 3, 2012

Making a clickable image and/or making a clickable container (Ext JS 4.x)

I had a case where I wanted to be able to click on an image and have it execute a transition within the Ext JS MVC framework. I originally looked into just using a regular button, but ran into several styling issues and most importantly a problem where the large image was being clipped. Due to a time crunch I threw a click listener on a container and set the container’s background using CSS.

See the following for the code: http://www.appfoundation.com/?p=471

Creating a dynamic TabPanel that contains dynamic GridPanels (Ext JS 4.x)


This was in a case where the data needed to be displayed in a tab for each category, so tab A had grid A, tab B had grid B, and so on. The TabPanel was also only displayed in certain cases, which meant that the TabPanel itself also had to be dynamic.

The issue with this is that the data within each of the grids on each tab was not refreshing when a new tab was selected. In order to get it looking right I ended up using a tab listener that refreshed the data in the grid on each tab selection. So if you selected Tab A the GridPanel in Tab A would have its store cleared and then reloaded.

See the following for the code: http://www.appfoundation.com/?p=469

Wednesday, May 2, 2012

Adding columns dynamically to a GridPanel (Ext JS 4.x)

See http://www.appfoundation.com/?p=467

There were examples on how to do this, just none of which I could get to work in Ext JS 4. Apparently you are not supposed to use the headerCt objects and with good reason, but I needed something that worked.

Tuesday, May 1, 2012

Calculating the scrollbar height of an iFrame (Ext JS 4.x)

See http://www.appfoundation.com/?p=464

The underlying problem was that I needed to drive the scrollbar on an iframe, but it was not entirely clear how to get the height of the scrollbar. I ended up having to derive it, and also found that the actual height is not set until some point after the content is loaded into it. There is an iframe onload event, but the scrollbar height is set at some point after that.

Monday, April 30, 2012

Writing an asynchronous task that takes a parameter (Ext JS 4.x)

See http://www.appfoundation.com/?p=462 on AppFoundation.

I needed to have a timer for each iteration of a loop and I needed to pass in parameters to have it behave differently depending on some loop specific settings. I couldn't find any examples so I resorted to looking through the source code and founds the "args" attribute on the task object.

Friday, April 27, 2012

Displaying an iFrame at 100% height and width in a dynamic Panel (Ext JS 4.x)

Some more work at AppFoundation: http://www.appfoundation.com/?p=453

Ultimately all of this is interacting with the HTML model so as long as you can translate into that you are able to almost anything. There were problems with this in terms of research because of the difference in how iFrames are handled in the various versions of Ext JS. In an earlier version there was even an iFrame component. While there are several components available for other versions of Ext JS, I couldn't get them working in the exact manner in which I wanted so I ended up just taking the simple approach. The simple approach being just putting the HTML tag for an iFrame in a panel.

See the link for the code.

Thursday, April 26, 2012

Resetting the selection in a combobox (Ext JS 4.x)

Resetting the selection in a combo box require the following three lines:


myComboBox.clearValue();
myComboBox.applyEmptyText();
myComboBox.getPicker().getSelectionModel().doMultiSelect([], false);

Loading JSON data from a web service into a combobox (Ext JS 4.x)

I posted this on AppFoundation's blog: http://www.appfoundation.com/?p=447

It explains the series of hoops I had to jump through in order to take JSON data from a web service and put it in a combo box in Ext JS 4.

What to include in app.js (Ext JS 4.x)

I am hosting this post on AppFoundation's blog: http://www.appfoundation.com/?p=442

It explains what to include in your application to avoid common dependency errors in Ext JS 4.