Main

Web 2.0 Applications Archives

December 8, 2007

Increasing dynamic web site performance with Zend Framework and Memcached

Using a good solution to cache your web application can increase the performance by 70%.

There are several good PHP caching solutions however, in this example we are going to use the Zend Framework Cache system with the power of Memcached.

What is memcached?
The Memcache module provides handy procedural and object oriented interface to memcached, highly effective caching daemon, which was especially designed to decrease database load in dynamic web applications.

Getting started.

So in the same way that we include any Zend Framework packages we need to include the Zend/Cache.php. Follow an example code:

<?php
require_once 'Zend/Cache.php';

$frontendOptions = array('lifeTime' => 20);
$backendOptions = array(array('host' => 'localhost','port' => 11211, 'persistent' => true));

$cache = Zend_Cache::factory('Core', 'Memcached', $frontendOptions, $backendOptions);

if (!$result = $cache->get('time') ){
$time = date('r');
echo "generated: " . $time;
$cache->save($time, 'time');
} else {
echo "cache hit: ". $cache->get('time');
}

?>

In the first 3 lines of this example we created our instance of the Zend_Cache class and configured the frontend and backend driver:

require_once 'Zend/Cache.php';

$frontendOptions = array('lifeTime' => 20);
$backendOptions = array(array('host' => 'localhost','port' => 11211, 'persistent' => true));

The frontend specifies only the lifetime that the cache data must be valid. For the Backend options we have to set up the localhost, the port and whether the daemon of memcached must be persistent.

The rest of code simply set and get a cached data.

Zend_Cache uses a modular approach to specify the frontend and backend drivers. The frontend driver determines what data is gathered and from your PHP script. The backend driver determines how the data is stored. In this example we are using the "Core" frontend driver, which is the top-level frontend driver which provides functionality that all other frontend drivers inherit. The "Memcached" backend driver provides memcached-based storage for your cached data.

In conclusion
The cache system can boost a lot the performance of your Ajax based application.
Using a memory based backend driver will speed up your code cache execution since the filesystem will not need to be touched during the execution of your scripts. Using memcache you will also be able to share your memory between machines enabling a cluster of machines to share the same cache.
There is also no support for SHM or database backends, and the frontend drivers available are not as numerous or mature as other Cache systems (such as PEAR::Cache).

April 30, 2008

Measuring the ROI of choosing Flex for Enterprise RIAs

The ROI index is a synthetic yet meaningful parameter used to express the benefit of making a project, as well as the benefit of making a certain choice related to a project, for example the technology to be used.

During my speech at the recent 360Flex Conference in Milan I presented the benefits achieved as a consequence of adopting Flex to re-design an enterprise application.

After an overview concerning the practical methods that can be used to evaluate the benefits and to calculate the Return On Investment (ROI), I presented a real-world case of an application for banking operations.

In that case, the benefit was measured in terms of the time saved to execute an ordinary operation (cashing a check) by using the Flex re-designed application respect the time that was formerly necessary to execute the same operation by using a "common" Oracle form-based application (simple html using the "traditional" logic of 1 click=1 page).

A tipically physical kind of measurement (time saved) was then translated into an economic parameter by valueing the time by the standard hourly wage of the staff involved in the operations of that kind.

The final passage was the calculation of the ROI formula.

The important and evident result was that the use of Flex contributed to leverage the ROI formula numerator (return) and to decrease its denominator (investment), for a double action of increment on the final result.

The slides of that speech can be found on SlideShare

September 4, 2008

How to build your own geographical based search engine

Our goal: provide to our website users the possibility to find all items (cinemas, restaurants, hotels...) within a defined range of their current locations, sorting results upon distance from them.

What we need: a database containing the latitude and longitude of the items, an interface to allow users to enter their current location (it can be a raw form or an interactive map, as you prefer), various software depending on your next choice.

Now we have at least 2 ways to reach our goal:

- Sql query:
it's the easier method, we already have data in our DB, we need only to execute a relatively simple query with a sub-query. Let's see an example in detail:

SELECT item_name, SQRT(POW((@user_lat - lat) * 111319.5 * COS(RADIANS(@user_lng)),2) + POW((@user_lng - lng)*110946.3,2)) as distance
from ( select item_name, lat, lng
     from items
     where lat >= (@user_lat - @range_degrees/2)
     and lat <= (@user_lat + @range_degrees/2)
     and lng >= (@user_lng - @range_degrees/2)
     and lng <= (@user_lng + @range_degrees/2)
) as boundary
WHERE distance < @range_meters
ORDER by distance;

Using this formula distance is given in meters, and you need to convert user choosen range in meters and degrees. Values 111319.5 and 110946.3 are based on this information.

Patrick O'Leary in his article on GIS based search use an Euclidian formula,I don't know if it's similar or it returns distance in miles etc., I haven't tried it so pay attention when you use his or my formula, do some testing!

- Lucene:
Apache Lucene is a high-performance, full-featured text search engine library written entirely in Java.
Local Lucene is an extension of Lucene providing an implementation of geographical searching. Another similar implementation is GeoLucene but it's still an earlier alpha and his developer is unable to work on this project. Both these software are faster on geographic queries than the unmodified Lucene and for sure faster than Zend_Search_Lucene too.
If you can use Java I recommend to choose Local Lucene, in his whitepaper pjaol shows a comparison beetween Mysql, Lucene and LocalLucene. Instead if you want to use the search capabilities of Lucene in PHP, you can use Solr and, in example, a client like this SolPHP or obtain a JSON response from the server. In this case you can use LocalSolr that is a porting of the LocalLucene library onto the Solr search server.
On GISSearch you can find all information needed to easily build your fast, scalable and reliable geographical search engine.

I hope it will be helpful to you and to your users.

December 18, 2008

Examples and slides of our latest events on PureMVC, BlazeDS, Java, AIR, and RIA User Interface design

Between October and November we held a couple of events for the italian Flex User Group (FlexGala) and Adobe Italy (Adobe TechConnection events).
These are the urls to some of slides and examples showed at those events:


December 22, 2008

Magento, a new e-commerce solution

We are proud to announce the release of our web solution for online sales of our client Studioarch.com. At the beginning of this project we had to choose the e-commerce solution that could fit our needs at best. This is a common situation for many web engineers and we know that there are plenty different solutions out there. In this post I will show you Magento Commerce and start with some pro and cons about the platform:

Pro:
Free and opensource platform
Feature-rich solution
Based on Zend Framework
Good SEO
Good support for localization
Fast-growing community
Easy update
Easily manageable extensions
and much more...

Cons:
Not much documentation (there is a growing wiki and a nice forum, but it is still difficult to find the answer you are looking for)
Importing products not yet fully supported (import script needs some tricks and workarounds to be used)
European tax system not fully supported (VAT, B2B, B2C..., check first if what you need is supported)
Internationalization may not be complete (depending on your language)
Still many bugs (but development and bug fixing is on the go, the last release is from 1.1.8 November 26, 2008)
and maybe some more...

And now some tips to the ones that want to use this platform:

Read the designer and user guides, they are good starting points to understand how Magento works.
Choose a base template that is as much similar as possible to what you want to achieve. You will then have to do much less work to reach your goal.
Use Firebug to help you modify and test your CSS without deploying every time.
Learn how to use the layout XML files.
If you want to modify the Magento Core code, learn how to override methods and classes, this will really help you and you will not have to throw away all your modifications when you will update Magento to a newer release.
If you need to insert a lot of products you should look into the import feature. It can really be a timesaver: in example you can build a script that queries your inventory database, writes a CSV file with all your product data and loads it directly into Magento. If you only have simple products, that's all you need to do. Problems arise when you have something more complex such as configurable products, so you will have to load configurable and related simple products first, then execute a few queries to link the configurable attributes and to relate each simple product to its configurable one (check Magento forum for further help).

We are happy to have chosen Magento for this project and I think we will use it next time also.

January 8, 2009

Importing REST web services in ActionScript with Flex Builder 4

Among the many Flex Builder 4 new features there is the possibility to import REST web services into ActionScript classes, in the same way that the previous builder allowed to import SOAP web services. It can import from XML as well as from JSON data. This new feature can obviously be used to import into ActionScript any kind of services that dynamically generate XML or JSON content.

For the following example I used the MAX preview version of Flex Builder 4, which has many interesting features and, while not yet complete, will become a very good IDE. The example will use a very simple JSP that returns some XML data, dynamically generated as a response to the client invocation. The JSP has contentType="text/xml;", accepts a numeric parameter length and returns a simple structure, with as many nodes as the length parameter. The service called with length=2 will return:

  <root>
    <content value="0"/>
    <content value="1"/>
  </root>

Now we can go to Flex Builder 4 and open the HTTP Service import dialog, right next to the Web Service one. The wizard will ask for the URL of the remote service and will be able to add the parameters accepted by the service. It is possible to define more operations, their parameters and request methods and also import as many HTTP services as we need. The next step will be the creation of the ActionScript classes, by selected the previously defined operations and configure the return type: the wizard will create all necessary classes and the methods to invoke the service, will hide from the developer the conversion between XML/JSON and ActionScript and provide with a transparent and object oriented set of classes ready to be used.

For the above XML the following classes have been created:
  Content.as - with a value property;
  XMLServiceTest - a class containing all the operations to be invoked on this service.
Both of these classes extend a base class, which contains the generated code, so we can safely modify the extending classes, as only the base ones would be overwritten in case of service changes.

Other interesting features of the new builder allow us to rapidly test the newly created services or even to enable paging and data management. By selecting a generated operation and the main application file we can have the builder generate a test datagrid and also all required events for it to work:

  <DataGrid id="DataGrid1" dataProvider="{result1.lastResult}">
    <columns>
      <DataGridColumn headerText="value" dataField="value"/>
    </columns>
  </DataGrid>

With a few clicks we have an application that exchanges strong typed data with a remote server, on top of XML/JSON.

By allowing a transparent conversion between XML/JSON data and ActionScript classes, this HTTP Service import feature makes the development easier for enterprise applications that use REST services or plain XML or JSON as a means of communication.

February 9, 2009

Securing your Solr server on Tomcat

Apache Solr does not have any security feature by its own, either at the document level or the communication level.
The simplest solution is the use of a firewall but this is not possible if you are using Solr as a Tomcat application. In this case you could want to require authentication only when accessing the entire Solr application or only some part of it, such as admin or update.

Let's see how to implement a basic authentication mechanism. We have to modify only two files: conf/tomcat-users.xml, inside the main folder of your Tomcat server, and WEB-INF/web.xml in your solr war file.

In tomcat-users.xml add:

<role rolename="yourRole"/>
<user username="yourUser" password="yourPassword" roles="yourRole"/>

In web.xml you have to specify the security restriction for your application:

  <security-constraint>
    <web-resource-collection>
      <web-resource-name> 
        Solr authenticated application
      </web-resource-name>
      <url-pattern>/*</url-pattern>
      <http-method>GET</http-method>
      <http-method>POST</http-method>
    </web-resource-collection>
    <auth-constraint>
      <role-name>yourRole</role-name>
    </auth-constraint>
  </security-constraint>
   <login-config>
    <auth-method>BASIC</auth-method>
    <realm-name>Basic Authentication</realm-name>
  </login-config>
  <security-role>
    <description>My role</description>
    <role-name>yourRole</role-name>
  </security-role>

In this example we protect the entire Solr application, but you can change the url-pattern node to protect only a part of Solr.

You could need to modify your client or your crawler to send the authentication header.
For example if you use PHP you have to send authentication parameters:

file_get_contents('http://yourUser:yourPassword@www.yourdomain.com:8080/solr/select/?q='.$query);

April 3, 2009

How to vertically center images in jCarousel and Thickbox3.

jCarousel is a jQuery plugin for controlling a list of items in horizontal or vertical order. The items, which can be static HTML content or loaded with (or without) AJAX, can be scrolled back and forth (with or without animation).
jCarousel is a good solution for a scrolling gallery of thumbnail images, but it doesn't have a built-in feature to vertically center images of different size.
This how to is based on the special example of jCarousel working together with Thickbox 3.

This is the original code used to create the html of each item of the carousel:


/**
* Item html creation helper.
*/
function mycarousel_getItemHTML(item)
{
  var url_m = item.url.replace(/_s.jpg/g, '_m.jpg');
  return '<a href="' + url_m + '" title="' + item.title + '"><img src="' + item.url + '" width="75" height="75" border="0" alt="' + item.title + '" /></a>';
};

Let's modify it using the jQuery Image, a Javascript object :


function mycarousel_getItemHTML(item)
{
  var url_m = item.url.replace(/_s.jpg/g, '_m.jpg');
  var img = new Image();
  $(img).attr('src', item.url).attr('title',item.title).attr('alt',item.title).css('border','0');
  return $('<a href="' + url_m + '" title="' + item.title + '"></a>').append(img);
};

Now it is possible to add an onload function as explained in this article.
When the image is downloaded we can work with its width and height and align it vertically:


function mycarousel_getItemHTML(item)
{
  var url_m = item.url.replace(/_s.jpg/g, '_m.jpg');
  var img = new Image();
  $(img).load(function () {
    $(this).hide();
    /* $(this).parent() is the <a> element,
     $(this).parent().parent() is the carousel item container */
    $(this).css('margin-top', ($(this).parent().parent().height()-$(this).height())/2);
    $(this).fadeIn();
  }).error(function () {
     // notify the user that the image could not be loaded
  }).attr('src', item.url).attr('title',item.title).attr('alt',item.title).css('border','0');
  return $('<a href="' + url_m + '" title="' + item.title + '"></a>').append(img);
};

In the same way it is possible to modify the horizontal alignment of the image:


  $(this).css('margin-left', ($(this).parent().parent().width()-$(this).width())/2);

It is also possible to change the height and width attribute of the Image object to fit images to the container. With some other tricks you could also create your personal loading animation.

February 4, 2010

Axis2, Spring and Annotations

Axis2 is a Web Services, SOAP, WSDL engine which current release, 1.5.1, comes with many interesting features among which there is the Spring Framework support.
Axis2 documentation offers some good example of Spring integration, such as the How to create a Spring-based POJO Web Service guide or the Axis2 Integration with the Spring Framework, but there's no mention of the use of Spring annotations.
Spring annotations work like a charm in Axis2 if you follow exactly the steps of the previous guide, but my tip is to build your service structure without using annotations in a first stage (unless you are already skilled in this field), then incrementally simplify your code adding Spring annotations.
Here is an example of a simplified application-config.xml when using Spring annotations with Axis:

<beans>

  <bean id="applicationContext" class="org.apache.axis2.extensions.spring.receivers.ApplicationContextHolder" />
  <context:component-scan base-package="service"/>
  <context:component-scan base-package="bean"/>
</beans>

Now all your beans inside the packages 'service' and 'bean' will be deployed on Spring application context start or refresh. To annotate a class as Spring bean just use the @Component annotation on your class.
If you want to initialize your service on deployment time, add the @PostConstruct annotation on your initialization method. If your bean needs to access another bean, just use the @Autowired annotation on your class field.
Here a simple example:

@Component
public class MyService{

@Autowired
private MyBean bean;

@PostConstruct
protected void init() {
//init operations
}

Don't forget to add the SpringBeanName parameter in your services.xml:

<parameter name="SpringBeanName" >myService</parameter>

Annotations simplify your life reducing time spent configuring every bean you need in your application and using them in Axis allows you to build complex WebServices with less code.
Have fun.

March 29, 2010

Flex WebService: how to list available operations at runtime

The Flex WebService component provides a operations property but this is set by the MXML compiler and contains only the operations listed in the tag.
If you want to access an unknown webservice and list at runtime all available operations, you can parse the WSDL xml by yourself or, more easily, use the WSDL parser of the Flex SDK.

Here a small example that I will explain later:


<mx:Script>
   <![CDATA[
      import mx.rpc.soap.LoadEvent;
      import mx.rpc.wsdl.WSDLOperation;

      protected function loadHandler(event:LoadEvent):void
      {
         if(event.wsdl) {
            for each(var op:WSDLOperation in event.wsdl.getPort().binding.portType.operations()) {
               trace(op.name);
            }
         }
      }
   ]]>
</mx:Script>

<mx:WebService load="loadHandler(event)" useProxy="false"
   wsdl="http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl"/>

One of the events for the WebService component is the load event. As stated on the reference the wsdl property of the LoadEvent class contains the WSDL object of the webservice just loaded. I'm not sure if this property could be null but I prefer to add a control to avoid a null pointer exception.
Now we have a WSDL object, but this class is not included in Flex language reference, so let's take a look to its source:


[ExcludeClass]
/**
* Manages a WSDL top-level definitions element. WSDL definitions
* may contain imports to other WSDL definitions. Only SOAP bindings are
* supported.
*
* @private
*/
public class WSDL

Well, this class will neither show up in the docs nor in the Flex Builder intellisense. This could indicate that it can be not stable or it could change with any SDK update, so pay attention!
Digging in the source I found that the interesting part is in parseBinding. Here for every tag parsed a WSDLOperation is created and added

to a WSDLPortType object. This portType is stored in a WSDLBinding object that is returned by this function. The parseBinding method is called by the method itself and in the parsePort method. parsePort is called by parseService that is in getService method. You can call getService directly or through getPort.

These two methods both accept a serviceName and a portName parameter, both optional. The WSDLBinding object is stored in a WSDLPort that you can access using the getPort method.

In this way you can build a dynamic client to access every WebService without the need to know its structure in advance.

July 3, 2010

Flex Webservice: how to list available parameters for each operation

In a previous post I explained how to list available operations provided by a WebService, parsing the WSDL document using some undocumented classes of the Flex 3 and 4 SDKs.
This time I want to give you some suggestions about the next step: listing parameters of every operation.
NB: most of the classes in the package mx.rpc.wsdl have the tag [ExcludeClass] so they could change with an SDK update or they can be not stable. Flex Builder intellisense will not work for these classes, so you have to import them manually.
Note that I'm testing this code using a WSDL from a Axis2 WebService, it may not work on WSDL with a different structure or it may need some tweaks.

<mx:Script>
	<![CDATA[
		import mx.rpc.soap.LoadEvent;
		import mx.rpc.wsdl.WSDLMessagePart;
		import mx.rpc.wsdl.WSDLOperation;
		import mx.rpc.xml.Schema;
		protected function loadHandler(event:LoadEvent):void
		{
			if(event.wsdl) {
				for each(var op:WSDLOperation in event.wsdl.getPort().binding.portType.operations()) {
					var param:WSDLMessagePart = op.inputMessage.getPart("parameters");
					if(param) {
						var schema:Schema = event.wsdl.schemaManager.getResourcesForURI(param.element.uri)[0] as Schema;
						var element:Object = schema.getNamedDefinition(new QName(schema.schemaConstants.xsdURI,param.element.localName),schema.schemaConstants.elementTypeQName);
						trace(element.definition, element.schema);
					} 
				}
			}
		}
	]]>
</mx:Script>

This small script, based on the code of the previous post, analyze the inputMessage of the WSDLOperation. If there is a WSDLMessagePart with name "parameters", it looks for the related Schema and then it searches the definition of the element of the WSDLMessagePart. This definition is just the XML of the complexType of the parameter, then you have to write your custom logic to use it. Some WSDL may non have the "part" node, instead there is the name of the element, you have to slightly modify the code above.

This is just a sketch and not a ready-to-use solution but it can point you in the right direction.

About Web 2.0 Applications

This page contains an archive of all entries posted to Comtaste Consulting | Enterprise RIA consulting and development in the Web 2.0 Applications category. They are listed from oldest to newest.

Spring is the previous category.

Many more can be found on the main index page or by looking through the archives.

Powered by
Movable Type 3.33