Archive for the ‘XML’ Category

Setting Database Connections in JBoss/ ATG

JBoss XML DS

ATG communicates to a database via JBoss via a dynamo server setup or in your home/localconfig directory if you’re not using specific dynamo servers. In this setup you specify the JNDI connection name which will then refer to an XML file which makes up part of your JBoss server. So to summarise ATG connects via its own JNDI config file which maps to an XML file on the JBoss server. JBoss then handles the connection out to the data source via a JDBC call – this can be any type of database or repository potentially.

Here’s how to set the database connections for something like Oracle. For MySQL etc… the procedure is pretty much the same and you can find example XML configs for these in your JBoss install the only real difference is the driver used for the connection.

First start with JBoss and setup the XML. Go to your servers deploy directory: \jboss\server\MY_SERVER_NAME\deploy. If you haven’t setup a server then this will be called default – if you’ve installed ATG then there will be a server called ATG. In your deploy directory there will be XML files normally with the mention of ‘ds’ in the file name, to let us know its for a data Source. If you go to:¬† \jboss\docs\examples\jca you should find example XML connection files here.

Alternatively using the below code we can create one for Oracle called something like ATG-Oracle-DS.xml.

In this XML file we basically set the JNDI reference name, the JDBC connection URL which is the database server IP/name along with the port and the SID (Service Identifier). We then set the schema that we want to connect to and it’s password. It’s the same for any database connection, although you’ll also see that we set the driver to use for the connection (more on this after the below XML)…










ATGOracleDS


jdbc:oracle:thin:@MY_ORACLE_DB_URL:1521:MY_SID


oracle.jdbc.OracleDriver


SCHEMA_NAME
PASSWORD


10


10




OK so the XML is pretty simple – you can have as many connections in one XML file as you need but sometimes it’s easier to keep them in separate files to identify connections. You can also MIX connections, so I can have a schema on Oracle, another on MsSQL and a third on MySQL and ATG can read and use data from all of these as part of its data anywhere architecture.

Here’s the gotcha – you MUST make sure the driver/ libary jar file is installed for your server to connect to your database. So go to your server’s lib directory e.g. \jboss\server\MY_SERVER_NAME\lib and for Oracle you will need a jar called ojdbc14.jar which contains the necessary classes for JBoss to connect to your database – generally JBoss does come with most database library jars but you may need to hunt this one down on Oracles website.

So We’ve set an XML file that specifies a connection for JBoss to use, we’ve added the necessary libary files to our JBoss server so it can make the connection. Finally we need ATG to be configured to use this connection, this is the really easy part!

In ATG the sources are referenced via the Dynamo servers localconfig, so for example in: \ATG\ATG2007.1\home\servers\MY_SERVER_NAME\localconfig\atg\dynamo\service\jdbc or if you’re not using Dynamo servers then just look in home\localconfig\atg\dynamo\service\jdbc.

If you’re building an external EAR file for your deployment then include this¬† in your Dynamo servers that you export with your EAR file. Anyway in this config directory you need to make a .properties file to set the JNDI connection to use. Just add the below 2 lines – the JNDIName variable should reference the JNDI name in your XML file.

$class=atg.nucleus.JNDIReference
JNDIName=java:/ATGOracleDS

And thats it! You should be able to map any database for use with ATG replacing the Solid database that comes with ATG.

Now a word of warning – it’s fine using additional databases for ATG but if you want to completely replace the Solid database, and in a production environment this is a must, you will need to load in the tables to your database for ATG to use, but I’ll write this up in a separate post – It’s pretty easy as ATG ships with various SQL setup scripts for you to use to achieve this.

Adding and changing Mod JK JVM route, URI encoding and thread settings for JBoss

jboss jvm uri threads

In your JBoss server there is a file that can be amended to alter the URI encoding and the number of threads used by JBoss. Additionally if you’re using mod_JK to link Apache HTTP and JBoss/Tomcat you can specify a JVM route parameter here that allows Apache to route incoming requests to the correct node.

To do this we need to look at the following file:

\jboss\server\[SERVER NAME]\deploy\jbossweb-tomcat55.sar\server.xml

In here we can amend a couple of parameters and add in a few extra values. For thread numbers and URI encoding look in the file for:

      
      

We can then edit the maxThreads parameter for more threads if needed although check your applications recommended threads, for instance ATG recommends no more than 250 threads per server. We can also add in the following parameter here for URI encoding which is: URIEncoding=”UTF-8″.

      
      

For the JVM route we need to amend this line in the server.xml file:


To the below, adding the jvmRoute parameter:


Doing this should help you with your mod_JK setups and remove a few issues between Apache and JBoss.

Setting the JDK version and compiler in JBoss for JSP pages

jboss jdk

If you need to run Java 1.5 in your JSP’s in JBoss 4.0.5.GA you can do so by editing a small setting in an XML file in your server directory:

jbossserver[SERVER NAME]deployjbossweb-tomcat55.sarconfweb.xml

You can then change the compiler version by un-commenting the code below which you will find in the web.xml.

      

Changing this will then allow for a different JDK to be used in your JSP’s.

Running multiple instances of Jboss on one server.

jboss ports

To run multiple Jboss instances on the one server is pretty easy – but remember that if you’re running something like ATG commerce you’re going to need a few Gb of memory to run just the one JBoss instance let alone multiples. So you may want seriously consider keeping separate VM’s for each server in your production environment depending on your application requirements e.g for heavyweight commerce keep them all as separate as possible. But for quickly building a development environment this is the way to go.

Anyway, the main thing to worry about with JBoss is the network ports setting as each instance needs it’s own port range, once you’ve done this then it’s all down to your application as to which port set it needs to use. So here’s how to set multiple instances and their respective ports. You’ll see that most if not all config for JBoss is done with XML files.

First we need to create an XML file to store our port bindings, thankfully we can use a sample one which you’ll find in: jboss\docs\examples\binding-manager\sample-bindings.xml and we can create a new directory to store this, something like jboss\bindings\binding.xml

You can see below a section of the code which sets up a ports definition for our server. At most I have done 4 configurations and actively run them all at once on a machine with 3Gb memory and it worked fine for my development requirements. Also I would recommend that you only use 1 bindings file however you can create and use multiple XML’s. Also you will see that we’re using ports 8180 instead of the typical 8080, this potentially leaves you 8080 free for another server giving you 5 in total – or it leaves the ports free if you need to map in an additional server on 8080, like FatWire. Depends on your architecture really, just remember 8080 is the default port setting of JBoss.



   
   
   
   

      

      
        
           socket://${jboss.bind.address}:3973
        
         
       

      

      
         
            1198 
         
          
      

      
         
          
      

      
         
          
      

      
         
          
      

      

      
         
            1201 
         
          
      

      
         
          
      

      
         
          
      
      
      

      
         
          
            

      

      
         
          
      

      

      
         
          
      

      
         
          
      

      

      
      
         
          
      

      
      
         
          
      
      
      
      
      
      
         
         
            
                jnp.disableDiscovery=false
                jnp.partitionName=${jboss.partition.name:DefaultPartition}
                jnp.discoveryGroup=${jboss.partition.udpGroup:230.0.0.4}
                jnp.discoveryPort=1102
                jnp.discoveryTTL=16
                jnp.discoveryTimeout=5000
                jnp.maxRetries=1
           ]]>
           
        
        
         
      

      
      
      
         
            :${port}/invoker/EJBInvokerServlet
        
         
          
      

        
      
         
            :${port}/invoker/JMXInvokerServlet
        
         
          
      

        
      
         
            :${port}/invoker/readonly/JMXInvokerServlet
        
         
          
      

    
      
      
         
            :${port}/invoker/EJBInvokerHAServlet
        
          
      

      
      
         
            :${port}/invoker/JMXInvokerHAServlet
        
          
      

      

      
      
        
         
      

      

      
      

      
         
          
      

      -->

      

      
         
            

     
     

     
     

     
       
     

      
         
            
            
               
                  
               
               
                  
               
               
                  
               
               
                  
               
               
                  
               
            
            
            
         
      

     
       
         
       
     
   
   ]]>
            
         
          
      

      
      
       
          
            socket://${jboss.bind.address}:4557/?dataType=jms&serializationtype=jms&timeout=0&leasePeriod=20000&socket.check_connection=false&marshaller=org.jboss.jms.server.remoting.JMSWireFormat&unmarshaller=org.jboss.jms.server.remoting.JMSWireFormat 
          
          
      
      
   

The ports can be incremented by 100 for each port in a new port setting, so for instance 8180 can be changed to 8280 to give you a new range. Just leave alone the section headed with:

You should be able to see the differences in the example bindings file between ports-01 and ports-02 setups and I’ve also commented each port change with so you can see which ports to change.

With that file done, next go to your JBoss install directory and then look for your server, if you’re using the default then it will be called… default. You can now duplicate this server if you need to and you’ll be able to run both at the same time with this tutorial. In here we look in the conf directory for a file called jboss-service.xml. The path to this looks something like this: \jboss\server\[SERVER NAME]\conf\jboss-service.xml

So open this file up and look in here for the following section:

   
     [SERVER NAME]
     ${jboss.home.url}/binding/binding.xml
     
       org.jboss.services.binding.XMLServicesStoreFactory
     
   

We then un-comment this section, e.g. remove the ‘–>’. Then we alter the ServerName attribute to match your server’s name and the StoreURL attribute to point to your new bindings file. Repeat this step for each of your servers. The servers name you enter is used to look up the ports configuration in the binding.xml, so if you left it as the default ports-01 then this will be the server name you need to enter.

And that’s pretty much it, if you have port conflict errors onyour startup then look in these files and also check that your application is set to use the particular ports, for instance using ATG we set the dynamo server to use RMI port xxxxx etc… which maps into your JBoss ports config. One other thing – you will always be able to see the ports being used in your JBoss logs if you need to debug.

Google Maps API part 1: Accurate Geocoding for UK Postcodes

googleMaps

Recently I had to build a system that would take an address, pass it to google and return latitude and longitude values. The result is then stored for later use and display on Google maps.

However, firstly I found that the default XML geocoding service provided by Google that allows you to do bulk geocoding on a data source and the geocoding provided by their maps API/ AJAX library (GClientGeocoder) had huge differences in results. Most postal codes passed to googles XML geocoding service were miles out or just not recognised. Yet when using the same postcode in the maps API when calculated on the fly the results were more or less spot on.

You can take a look at a tutorial for using Googles XML geocoder service, PHP and MySQL here. They suggest that this way is good if you don’t want to repeatedly geocode the same address again and again and if you want to do bulk geocoding.

Which would be nice, if it was actually accurate! But this still leaves me with having to do bulk uploads or geocoding and get accurate results to build, for instance, a store locator around the data.

The solution is simple, we can utilise the Google maps API to do the geocoding for us on the fly and store the result passed back using some simple AJAX to send the data to PHP/ MySQL. While I geocode my records at the time of their entry, in the example below, you could just as easily use this to create some sort of bulk update. Check out my tutorial here about using AJAX to pass form data to PHP if you’re new to this.

Firstly you will need to signup to get a couple of free API keys from google, you don’t require much to get them and they’ll work just fine for a localhost.

Maps API key: http://www.google.com/apis/maps/signup.html
AJAX Search API key: http://code.google.com/apis/ajaxsearch/signup.html

OK so now we create a HTML page, form.htm, this will call in the Javascript libraries and do the geocoding work.



We also build a function that creates an XML object in the DOM to store the data, which will then get passed to the PHP page. This works in exactly the same way as my tutorial here.


This chunk of code above is what utilises the google maps keys, to pass the data to google, geocode it and return the record and I've written this inside of a function that gets called on the form submission, which in turn then uses the previously declared XML creation function.

The final stage of this HTML page is of course the form which sends the data and a span tag that displays the results if successful.


Address Line 1:
Address Line 2:
Address Line 3:
Town:
Postcode:
 

Server-Response:

This then just leaves us the PHP page (post.php) that will then post the results, again nothing too disimilar to my previous tutorials on this. This is the bit where you would pass in the $_POST parameters and store them using MySQL etc... or save them to a text file.


And there we have it, accurate geocoding from google that can be used as a service when data is entered, or you could use this same method by passing in XML created from your database and iterating over this passing each result to the API and returning a value.

Now you can build a store locator or whatever that actually returns accurate results, also you can then use this to integrate your database better with the full Google maps API - showing maps, placing markers on maps etc..

Using Javascript/ AJAX to post HTML form data

javascript form ajax php

Why would you need to do this? Well for instance if you were using 3rd party AJAX APIs and you wanted to capture the data from them perhaps, or maybe you just have a complex form.

Or you could use this for form validation to return errors from the server without refreshing the browser, for example, if the data already exists in a database you could let the user know.

Either way its pretty simple. Basically we just use javascript to post the form object over http to a serverside page – e.g. PHP, JSP, ASP etc…

First of lets have a look at the javascript


And thats it, as for the HTML form, only thing to note is that the form action calls the sendData function:

* Address Line 1:
Address Line 2:
Address Line 3:
* Town:
* Postcode:
 
Server-Response:

Oh and of course the post.php page, in here you could add in your validation, check the database etc... what ever you ourput to the page (using print, echo etc...) can be then sent back to your form page and displayed without the user leaving your form page or refreshing the browser.


Creating XML from PHP/ MySQL for use with SPRY

So lets say for example you have a table in your database and you want to return some results, pretty easy with PHP/ MySQL and I dare say easy enough with other languages.

Now rather than return the results to the page and format them etc… you want to instead put them to an XML file – why? Well because creating a dataset in XML allows you to make use of various things both from a design point of view and from the prespective of user interaction. I’m of course talking about AJAX here (but also useful for XSLT etc…).

So assuming you are using PHP5, MySQL5 you can use the template below to do this. I’ve also used Adobe’s SPRY here, but jQuery or straight forward Javascript is easy enough. I’m going to assume you are also using SPRY – but there’s an example at the bottom using plain old javascript.

First stage: Create PHP page to build XML from database query

So this is my page: queryBuilder.php

It takes a parameter parsed via the URL GET method (q) and then loads the data based on this. Using this you can create a lot of different XML datasets served from just one page. Replace [text] with your own values.

createElement(‘[parent node]’);
$root = $doc->appendChild($root);
//create a document header to tell browsers what type of file this is
header(“Content-type: text/xml”);
//fetch data from your database table
$myList = mysql_query(“SELECT
ID,  Name
FROM mytable
ORDER BY Name ASC”);
// process one row at a time
while ($row = mysql_fetch_assoc($myTrades)) {

// add node for each row
$occ = $doc->createElement(‘[child node name]’);
$occ = $root->appendChild($occ);

// add a child node for each field
foreach ($row as $fieldname => $fieldvalue) {
$child = $doc->createElement($fieldname);
$child = $occ->appendChild($child);
$value = $doc->createTextNode($fieldvalue);
$value = $child->appendChild($value);
} // end foreach
} // end while

// get completed xml document
$xml_tradesList = $doc->saveXML();
//return xml page to the browser
echo $xml_tradesList;
} //end if q=

} //end if isset

//close db connection
mysql_close();
?>

Second stage: Create page to filter and display data.

So we can now fetch our dataset and use some javascript/AJAX call to get the XML. For simplicity I’m going to use SPRY, Adobes library, but you can just as easily use jQuery.

Creating a page called queryBuilder.htm first thing is to add in the framework libraries that you need available from Dreamweaver install or free from Adobes site (as linked):


Next we need to define our datasets – if you’re used to SPRY this should be easy enough for you.

So thats essentially it, SPRY calling in records from your database via a PHP page. Of course I’m assuming that you know how to display records in SPRY? No? Well here’s how to do it quickly for a select menu!

//declare a region for SPRY

//declare a region that will repeat all results in a loop

Easy huh?

Alternative to SPRY do it in Javascript

So with just Javascript a chunk of code such as below will do much the same thing as the SPRY code just you have to write more.

Make a file queryBuilder.js

//create variable to store the output of queryBuilder.php
var xmlhttp

// function to create an XML object
function GetXmlHttpObject()
{
if (window.XMLHttpRequest)
{
// code for IE7+, Firefox, Chrome, Opera, Safari
return new XMLHttpRequest();
}
if (window.ActiveXObject)
{
// code for IE6, IE5
return new ActiveXObject(“Microsoft.XMLHTTP”);
}
return null;
}

function showList(str)
{
xmlhttp=GetXmlHttpObject(); //function defined below
if (xmlhttp==null)
{
alert (“Your browser does not support AJAX!”);
return;
}
var url=”queryBuilder.php”;
url=url+”?q=”+str;
//this fetches the XML data in the DOM from the queryBuilder.php page
xmlhttp.onreadystatechange=stateChanged;
xmlhttp.open(“GET”,url,true);
xmlhttp.send(null);
}

function stateChanged()
{
//if XML has been loaded and is ready
if (xmlhttp.readyState==4)
{
// display the xml from queryBuilder.php to this HTML element
document.getElementById(“[Some HTML element]”).innerHTML=xmlhttp.responseText;
}
}

So now you can include this on your html page and call in the XML by calling the js function showList([data to load])