Wednesday 30 July 2008

Telco APIs

The communications industry (telecommunications and internet) must have the largest number of standards specifications - from the layering of the network model, to individual protocols inside each layer. Even the same standard can be defined by more than one standard bodies - ITU-T, ESTI, ANSI, etc. The standards are very necessary in the communications industry. Afterall, communications are all about being able to interwork/interact with each other. So a common language is needed.

Traditionally, the standards stayed at the protocol level - i.e. to ensure that different systems/subsystems can communicate with each other. Typical exmaples are SS7 (and SS7 based protocols), VoIP protocols (SIP, H.323). More recently, as the industry matures, standard programming APIs have become prevalent, e.g. Parlay/X, OSS/J, JAIN APIs. These APIs enables inter-operability among different systems and system vendors. It also cuts down the effort of individual software vendors because much of the specification and documentation have already been done by the community/expert groups. Leveraging these standard APIs increases the software vendors' productivity and ensures smoother integration with other systems.

I have been involved in service development using legacy Service Creation Environment (SCE), which provides proprietory drag-and-drop type of 'programming' environment (think Visio). The legacy SCE boasts that no programming experience is needed and only drawing of the flow diagram is required. On the surface, this seems an attractive paradigm (apart from lack of documentation - zero documentation really), however, once you need to go beyond the surface, it's nothing but pure frustration. When you are stuck, you have to ask the vendor to provide another service building block (SBB) in order to put it onto the flow diagram. On the contrary, in a JAIN SLEE environment, a developer can write new SBBs using Java following the JAIN APIs and architecture. This gives the developer power and flexibility over the legacy approach.

Friday 25 July 2008

Consuming WCF Web Service Using Java Client

[Updated on 2009-06-22] The JSE's native wsimport tool has been added along with custom binding in a more recent post - JAXB Custom Data Binding.

From the previous post I showed how to create a simple web service using WCF and consume it with a windows console application written in C#.

To have the same web services consumed by a Java client, I needed to make the web service WS-I Basic Profile 1.1 compliant so that it becomes portable cross-platforms. To do this, it is simply a matter of following instructions on MSDN. In my case, I modified Web.Config file: in <services> section I changed the wsHttpBinding into basicHttpBinding and removed the identity tags. The resulting snippet:


    
        
        
        
        
    

IntelliJ IDEA

To generate the Java web service client, I created a Java project in IDEA 7.0.2. Then right-click on the src tree to select New -> Web Service Client, then paste in the wsdl url (http://localhost/PromoService.svc?wsdl). Bingo, IDEA generates all the interface and class files, together with the client test code. I guess it is using JAXB under the hood. Adding the bits into the client test code resulted:

import svdemo.PromoService;
import svdemo.PromoInfo;

public class SvdemoClient {
  public static void main(String[] argv) {
      svdemo.IPromoService service = (new PromoService()).getBasicHttpBindingIPromoService();
      //invoke business method
      String keywords = "action";
      if(service.hasPromo(keywords)) {
          PromoInfo promo = service.getFirstPromo(keywords);
          System.out.println("promo:"+promo.getPromoName().getValue()
                  +","+promo.getPromoDateTime());
      }   else {
          System.out.println("nothing");
      }
  }
}

Notice how the service is instantiated (code not as nice as in C# version). Also, the PromoInfo class's members data type are of JAXBElement and XMLGregorianCalender..., which are not as nice as native primitive types. But it works - here is the output:

promo:Batman The Dark Knight,2008-07-30T10:00:00

NetBeans 6.0

I created a Java application project in NetBeans. From the project's source branch, right-clicking will bring up the New -> Web Service Client option. Providing the WSDL URI and selecting JAX-WS style will generate the WS client classes. The results are similar to IDEA, the exact same client code (see above) can be used to test the client. However, it is extremely slow so that I thought NetBeans froze. This happens to almost every step onwards. I eventually gave up on NetBeans. Maybe it is time to upgrade.

CXF

Apache CXF is the 2nd generation XFire. By default, it generates JAXB style binding. It came with wsdl2java utility. To generate the client code from wsdl, I used the following commands:

mkdir d:\projects\svdemocxf
wsdl2java -d d:\projects\svdemocxf -client -ant http://localhost/PromoService.svc?wsdl
I then moved all the source files into a src directory. Then build the project.
D:\projects\svdemocxf>ant build
D:\projects\svdemocxf>ant IPromoServiceClient
Buildfile: build.xml

compile:
    [javac] Compiling 15 source files to D:\projects\romen\build\classes

IPromoServiceClient:
     [java] Invoking hasPromo...
     [java] hasPromo.result=false
     [java] Invoking getFirstPromo...
     [java] getFirstPromo.result=null
     [java] Invoking getKeywordsFromMySpace...
     [java] getKeywordsFromMySpace.result=

BUILD SUCCESSFUL
Total time: 4 seconds

Note that the environment variable CXF_HOME had to be defined and point to the CXF installation directory for the ant build.xml file to work.

I added the client testing code similar to the one above:

package svdemo;
import org.datacontract.schemas._2004._07.svdemo.PromoInfo;
import org.tempuri.*;

public class Program {

 /**
  * @param args
  */
 public static void main(String[] args) {
  IPromoService service=(new PromoService()).getBasicHttpBindingIPromoService();
  String keywords="action";
  if(service.hasPromo(keywords)) {
   PromoInfo promo=service.getFirstPromo(keywords);
   System.out.println("promo:"+promo.getPromoName().getValue()
     +","+promo.getPromoDateTime());
  } else {
   System.out.println("nothing");
  }
 }
}
To run the test, I added the following target to the build.xml file:

    
 

Running the RunTest target yields:

D:\projects\svdemocxf>ant RunTest
Buildfile: build.xml

compile:
    [javac] Compiling 16 source files to D:\projects\svdemocxf\build\classes

RunTest:
     [java] promo:Batman The Dark Knight,2008-07-30T10:00:00

BUILD SUCCESSFUL
Total time: 4 seconds

Axis2

Apache Axis2 (v1.4) comes with the wsdl2java utility which generates java source code from WSDL file. Using the following command:

wsdl2java.bat -o \projects\svdemoAxis -p svdemoClient -uri http://localhost/PromoService.svc?wsdl

This generates the client stub class PromoServiceStub and dozens of inner classes - one for each input/output parameter and data type! The client test code ends up like this:

package svdemoClient;

import java.rmi.RemoteException;
import org.apache.axis2.AxisFault;
import svdemoClient.PromoServiceStub.PromoInfo;

public class Program {

 /**
  * @param args
  */
 public static void main(String[] args) {
  try {
   PromoServiceStub service=new PromoServiceStub();
   String keywords = "action";
   
   PromoServiceStub.HasPromo hasPromoPara=new PromoServiceStub.HasPromo();
   hasPromoPara.setKeyword(keywords);
   PromoServiceStub.HasPromoResponse hasPromoResp = service.HasPromo(hasPromoPara);
   if(hasPromoResp.getHasPromoResult()) {
    PromoServiceStub.GetFirstPromo firstPromoPara=new PromoServiceStub.GetFirstPromo();
    firstPromoPara.setKeyword(keywords);
    PromoServiceStub.GetFirstPromoResponse firstPromoResponse = service.GetFirstPromo(firstPromoPara);
    PromoInfo promo = firstPromoResponse.getGetFirstPromoResult();
    System.out.println("promo:"+promo.getPromoName()
      +","+promo.getPromoDateTime().getTime());
   } else {
    System.out.println("nothing");
   }
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  
 }

}
Compiling and running it in Eclipse 3.4 yields:
promo:Batman The Dark Knight,Wed Jul 30 10:00:00 EST 2008
As shown above, the code is very UGLY! For each input parameter and output response, a class has to be instantiated (even when the parameter is simply a string). This not only makes the code long, but also very hard to read. This is the ADB binding used by Axis2 by default. Changing the binding style into xmlbeans or jibx slightly improves the esthetic and readability of the code, but not much. The following test client code snippet is written against XMLBeans binding style from Axis:
String keywords = "action";
HasPromoDocument hasPromoDoc = HasPromoDocument.Factory.newInstance();
hasPromoDoc.getHasPromo().setKeyword(keywords);
HasPromoResponseDocument hasPromoResp;
hasPromoResp = service.HasPromo(hasPromoDoc);

if(hasPromoResp!=null && hasPromoResp.getHasPromoResponse().getHasPromoResult()) {
 GetFirstPromoDocument firstPromoDoc=GetFirstPromoDocument.Factory.newInstance();
 firstPromoDoc.getGetFirstPromo().setKeyword(keywords);
 GetFirstPromoResponseDocument firstPromoResp=
  service.GetFirstPromo(firstPromoDoc);
 if(firstPromoResp!=null) {
  PromoInfo promo=firstPromoResp.getGetFirstPromoResponse().getGetFirstPromoResult();
  System.out.println("promo:"+promo.getPromoName()
    +","+promo.getPromoDateTime().getTime());
 }
}
This article from DeveloperWorks gives more insights and examples on the different types of Axis2 bindings. As of Axis2 v1.4, it came with a JAXB experimental support. The above is just my feeble attempt on Axis2. However, Axis2's wsdl2java is quite capable of generating esthetic code - Eclipse 3.4 uses Axis under the hood (using JAXB I guess) to generate web service clients.

Eclipse Ganymede JEE Distribution

Eclipse Ganymede (v3.4) has an option to add new Web Service Client. However, it requires you to specify a Server - this is totally wrong, there is absolutely no need to have a server definition to generate WS client code. However, I just played along and defined a Tomcat 6.0 server. It allows me to continue with the WS Client wizard. Then, after I specified the WSDL URI, it gave me the error:

IWAB0503E Unable to update Java build path. Please check your system environment.
    Java Model Exception: Java Model Status [Build path contains duplicate entry: 'D:tools/eclipse/plugins/org.apache.axis_1.4.0.v200806030120/lib/axis.jar' for project 'svdemoAxis']
    ...
Days later, I upgraded one of the Eclipse plugins (which was auto-detected and suggested by Eclipse), then things were better. Retrying generating the web service client resulted in a new WebServiceProject project being created. I then added the testing client:
package svdemoClient;
import java.rmi.RemoteException;

import org.datacontract.schemas._2004._07.svdemo.PromoInfo;
import org.tempuri.*;

public class Program {

 /**
  * @param args
  */
 public static void main(String[] args) {
  String keywords="action";
  IPromoService service=(new IPromoServiceProxy()).getIPromoService();
  try {
   if(service.hasPromo(keywords)) {
    PromoInfo promo=service.getFirstPromo(keywords);
    System.out.println("promo:"+promo.getPromoName()
      +","+promo.getPromoDateTime().getTime());
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

}
Note that the promotDateTime field generated is of java.util.Calendar type, not XMLCalendar.

Related Posts:

Thursday 24 July 2008

WCF In 1 Hour

As part of a product concept study, I needed to prototype a web service to be consumed by a telephony service. This is to simulate a targeted promotion campaign in the telco environment.

The web service allows the consumer to check by keyword for any related promotions. If there are any, the consumer can retrieve the promotion and use the details of the promotion information - e.g. send a SMS or email to the subscriber to notify him/her about the promotion. I had the following in mind about the promotion web service:

  1. to store the promotion data in an xml file
  2. have a boolean service to check whether there are any promotions in the database with matching keyword
  3. have another service method to return the promotion data (an object/composite type) with matching keyword
  4. the promotion information need to be short and concise, making it suitable for sending in a SMS
The XML file I chose to create looked something like this:

 
  New Years Eve Concert
  The biggest event of the year. Artists from all around
  the country.
  Domain
  2008-12-31 20:00:00
  New Year's Eve
 
 
  Batman The Dark Knight
  
   Meet stars in Batman in person - Chritian Bale, Michael Caine.
  
  Star City
  2008-7-30 10:00:00
  Batman, action
 
 
  Jazz Night
  
   Jazz lovers' do not miss this once in a lifetime opportunity.
  
  The Jazz Club
  2008-10-30 21:00:00
  Jazz
 

After a short consideration, I decided to use .NET WCF for the web service and LINQ for the XML querying. The only problem is that I knew nothing about WCF and little about LINQ (I lived in the Java land). But it did not stop me. In fact, it made it more exciting.

The first thing I did was to create a WCF project in VS.2008. VS.2008 made it extremely easy. I then modified the auto-generated service interface and the service implementation files:

The serivce interface is IPromoService

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace svdemo {
    [ServiceContract]
    public interface IPromoService {
        /// 
        /// Tests whether there are any promotions with matching keyword.
        /// 
        /// <param name="keyword">the keyword to be matched. Case in-sensitive, single word only</param>
        /// <returns>whether there are any promotions with matching keyword</returns>
        [OperationContract]
        bool HasPromo(string keyword);

        /// 
        /// Get the first promotion which matches the given keyword.
        /// 
        /// <param name="keyword">case in-sensitive, single word only.</param>
        /// <returns>The first promotion with matching keyword.</returns>
        [OperationContract]
        PromoInfo GetFirstPromo(string keyword);
    }


    // Use a data contract as illustrated in the sample below to add composite types to service operations.
    [DataContract]
    public class PromoInfo {
        string promoName;
        string promoDescription;
        string promoVenue;
        DateTime promoDateTime;

        public PromoInfo(string name, string desc, string venue, DateTime dt) {
            promoName = name;
            promoDescription = desc;
            promoVenue = venue;
            promoDateTime = dt;
        }
        [DataMember]
        public string PromoName {
            get { return promoName; }
            set { promoName = value; }
        }

        [DataMember]
        public string PromoDescription {
            get { return promoDescription; }
            set { promoDescription = value; }
        }

        [DataMember]
        public string PromoVenue {
            get { return promoVenue; }
            set { promoVenue = value; }
        }

        [DataMember]
        public DateTime PromoDateTime {
            get { return promoDateTime; }
            set { promoDateTime = value; }
        }
    }
}

The service implementation PromoService:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Xml.Linq;

namespace svdemo {
    public class PromoService : IPromoService {
        XDocument doc;
        public PromoService() {
            doc = XDocument.Load(@"D:\projects\SigvalueWS\svdemo\svdemo\data.xml");
        }

        public bool HasPromo(string keyword) {
            if (keyword == null)
                return false;

            string kw = keyword.ToUpper();
            var q = from p in doc.Descendants("Promotion")
                    where ((string) p.Element("Tags")).ToUpper().Contains(kw)
                    select p.Element("Name").Value;
            return (q.Count() > 0);
        }

        public PromoInfo GetFirstPromo(string keyword) {
            if (keyword == null)
                return null;
            string kw = keyword.ToUpper();
            var q = from p in doc.Descendants("Promotion")
                    where ((string) p.Element("Tags")).ToUpper().Contains(kw)
                    select new PromoInfo(p.Element("Name").Value,
                        p.Element("Description").Value,
                        p.Element("Venue").Value,
                        DateTime.Parse( p.Element("DateTime").Value));
            PromoInfo promo = q.First();
            return promo;
        }
    }
}

Running this project (Ctrl+F5) will deploy the web service onto a test web server and the wsdl can be obtained from the url http://localhost:2144/PromoService.svc?wsdl

To test the consumption of the web service, I created a console application project in C#. Adding a service reference (by copying the above URL into it) automatically generates the required web service client entry point code, client proxy, and the DTO PromoInfo class. So consuming the service is a no-brainer:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using svdemoClient.ServiceReference;

namespace svdemoClient {
    class Program {
        static void Main(string[] args) {
            PromoServiceClient client = new PromoServiceClient();
            string keyword="Jazz";
            if (client.HasPromo(keyword)){
                PromoInfo promo=client.GetFirstPromo(keyword);
                Console.WriteLine(
                    String.Format("got {0}, {1}", 
                    promo.PromoName, promo.PromoDateTime)
                );
            }else
                Console.WriteLine("nothing");
            System.Threading.Thread.Sleep(3000);
            client.Close();
        }
    }
}

Although this is my very first attempt to use WCF and LINQ to XML, the whole thing took me an hour and a bit and majority of the time was used in googling on how to use LINQ to XML.

Note: it is better to modify the transport setting to use Basic HTTP instead of TCP to improve interoperability. See here for more details.

Monday 21 July 2008

WPF Splash with ProgressBar

There are some excellent articles on Quantum Bit Designs on WPF and cross-thread updates. I borrowed one of them to implement a splash screen in my WPF demo application.

On start up of my WPF GUI application, I want to show a splash window with a progress bar underneath. At the same time, I do some potentially time-consuming tasks, such as openning a database connection and load some reference data into memory. Since the duration of this type of operation cannot be known up front and the percentage of each step wrt the entire operation cannot be determined either, it is sensible to use an undeterministic progress bar. The SplashScreen.xaml file is shown below:


    
        
            
            
        
    

The trick is to have a System.ComponentModel.BackgroundWorker to perform the long running operation. The initialisation operation class is defined as such:

public class InitOperation {
        bool completed = false;
        string errorDescription;
        /// 
        /// the operation is either completed successfully (true) or
        /// aborted due to exceptions (false).
        /// 
        public bool Completed {
            get { return completed; }
        }
        /// 
        /// the error text to be displayed in GUI in case of error
        /// (i.e. completed==false)
        /// 
        public string ErrorDescription {
            get { return errorDescription; }
        }

        public InitOperation() {
            completed = false;
            errorDescription = String.Empty;
        }

        public void Start() {
            BackgroundWorker worker = new BackgroundWorker();
            worker.DoWork+=new DoWorkEventHandler(worker_DoWork);
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
            worker.RunWorkerAsync();
        }

        void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
            OnComplete(EventArgs.Empty);
        }
        /// 
        /// Upon operation completion, fire a Complete event so that the 
        /// observer can receive and act on it.
        /// 
        protected virtual void OnComplete(EventArgs e) {
            if (this.Complete != null) {
                this.Complete(this, e);
            }
        }
        /// 
        /// The long-running operation is performed here.
        /// 
        void worker_DoWork(object sender, DoWorkEventArgs e) {
            try {
                // long-running operation goes here.
                completed=true;
            } catch (Exception ex) {
                completed=false;
                errorDescription = ex.Message + "\n" + ex.StackTrace;
            }
        }
        /// 
        /// the event to be fired upon operation completion
        /// 
        public event EventHandler Complete;
    }

The core of the InitOperation is in the Start() method. It creates a background worker, adds the event handlers and then executes the worker in another thread. Once the worker completes, it will fire a Complete event. Whoever is listening to the event will receive it. So I need to have the Splash screen (running in the GUI thread) to register to the event and handle it:

public partial class SplashScreen : Window {
        InitOperation _operation;

        public SplashScreen(InitOperation worker) {
            this._operation = worker;
            this._operation.Complete += new EventHandler(_worker_Complete);
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(Splash_Loaded);
        }

        void _worker_Complete(object sender, EventArgs e) {
            if (_operation.Completed) {
                MainWindow mw = new MainWindow();
                Close();
                mw.Show();
            }
            else {
                MessageBox.Show("Cannot initialise application:\n"+_operation.ErrorDescription,
                "Fatal Error", MessageBoxButton.OK, MessageBoxImage.Error);
                Close();
            }
        }

        void Splash_Loaded(object sender, RoutedEventArgs e) {
            _operation.Start();
        }
    }

The SplashScreen class is very straight forward. It registers itself to the InitOperation's Complete event and then Start() the initialisation operation. It takes an InitOperation as input parameter for its constructor. This wiring up is done at the App.xaml and App.xaml.cs.


 
  
   
    
   
  
 

Instead of specifying the StartupUri, a Startup event handler is defined in App.

public partial class App: System.Windows.Application
 {
        private void Application_Startup(object sender, StartupEventArgs e) {
            SplashScreen splash = new SplashScreen(new InitOperation());
            splash.Show();
        }
 }

Thursday 17 July 2008

Skype on N95

I got a 'free' Nokia N95 handset from 3 a few weeks ago. It came with a 3 Skypephone client, which offers free Instant Messaging (IM) and skype-to-skype voice calls. The 3 Skypephone client was developed especially for the mobile operator 3. Therefore, you can only use the 2.5/3G network as the transport layer. The client does not offer any option to choose the access point. So if you are not a 3 subscriber, this skype client is useless.

A better option is to use Fring available from www.fring.com. Fring combines several IM clients into one - Skype, MSN, SIP, Google Talk, etc. It offers free IP calls between Fring and Fring (or native IM clients) and instant messaging. You can even make mobile calls from within the Fring client. It allows you to choose which access point to use - it can be GPRS, 3G, WiFi connections, so you are not tied to a particular operator. A problem with Fring (probably a Skype server problem) is that it sometimes does not load all the contacts from all the IM servers - e.g. some of my Skype contacts are consistently missing in the Fring contact list. Otherwise, Fring is a pleasure to use.

A similar product to Fring is Nimbuzz, which offers pretty much the same user experience as Fring.

Not yet published by Skype, Skype is also working on mobile versions of Skype client. A beta version is available for N95. Installation is easy, simply connect to skype.com/m from N95 and follow the instructions. Like Fring, it allows you to choose the access point, so you can use WiFi if you wish. This client gives you the capability of instant messaging between skype contacts. However, making voice calls is not supported. What makes it worse is that it can charge you skype out rates without you even knowing it. What happens is that at installation and login time, it forces you to enter your mobile phone number. When someone makes a skype-to-skype voice call to you (when you are on mobile skype), it diverts the call to your mobile number and you get charged for the skype-out (yes, the receiving end pays)! Therefore, this client is only good for chats, definitely not for voice calls.

From the partnership with 3 and this new mobile skype client, it is evident that Skype does not want to compete with the Telcos, but rather works with them. This is contrary to the thought that IM vendors are a threat to telco. I think this is partially because VoIP is heavily regulated/restricted by authorities in many countries and VoIP operators usually have to pay a hefty fee to the incumbent telcos. Therefore, Skype seems to be hedging their bet both ways.

Monday 14 July 2008

Of Parenting and Management

If you are unfortunate enough to get sick in Sydney, you must be prepared to be extra patient and do not let the frustrating experience of seeking medical help exacerbate your condition. Usually, waiting time of 1-2 hours is guaranteed before you can see a GP at a medical center. Today, due to temporary closure of a major local medical center my family and I had to wait 5.5 hours to see a GP.

While waiting, I was browsing through the news letters piled on the coffee table in the waiting room. One article drew my attention - it's titled Sibling rivalry. What parents can do. It provides several tips for parents on how to deal with sibling rivalry. As I read through them, they looked remarkably familiar. Then it struck me, I have seen similar pointers from a management book - Leading the Professionals - How to Inspire & Motivate Professional Service Teams. There is a chapter called Manage Interpersonal Disagreements in that book. Here, I put the pointers side by side between the two:

Your Health News Letter Leading Professionals book
1. Spend special time with each child on a regular basis Tell it again and again.
2. Show and tell your kids frequently that you love each one of them. Helps team members to improve by giving feedback constructively and sensitively
3. Let each child have some private space and special things they don't have to share. Make sure team members have the resources to accomplish tasks
4. Try not to compare children Treats individuals fairly. Considers the feelings of others when giving opinions.
5. Negotiate some clear rules with your children. If you then have to step in, you are acting on the rules, not taking sides. Make no judgements and describe the problem as being one for you, the team as a whole and the individuals concerned.
6. Help your children express their feelings in words or play. Ask them in turn to describe what is going on as they see it.
7. Try not to take sides. Listen to each child in a conflict so each feels heard. Ask them in turn to describe what is going on as they see it. Ask each person to summarize what the other person has said.
8. Often it is better to let kids sort out differences themselves. Help them to listen to each other's feelings and teach them to work out fair solutions together. Step in if things are getting out of control or if someone is about to be hurt. Ask each person in turn to indicate points of agreement. Ask each of them in turn to indicate points of disagreement and to suggest ways to resolve them. Agree a date, perhaps a month later, for the three of you to get together to review progress.

Seems that handling sibling rivalry is not that different from managing a professional team. One of my ex-colleagues did compare his team with kids from time to time. What makes managing a professional team more challenging then bogs down to the size of the team.

5.5 hours later, we finally got to spend 5 minutes with the doctor before being kicked out. If you come from Asian countries, you may have been taking things for granted - if I can afford to see a doctor, I should be able to see one in no time and have his/her full attention. Things are simply not so in Australia. For those who are contemplating migrating to Australia, think again...

Thursday 10 July 2008

Xenophobia

I have travelled to many countries and met people from many different backgrounds and points of views due to the nature of my work. Some people are more open-minded and tollerant than others; and of course, there are the occasional xenophoics that you can find in any country.

Xenophobics are extremely easy to identify: if you have expressed yourself which did not agree with his/her beliefs, then he/she will throw you the tell-tale line of "Go back to your own country!" I am sure many frequent overseas travellers or immigrants have experienced it at least once or twice.

In the computing world, such xenophobic behaviour also exists. In a recent online article on Java Lobby, the subject of whether Java should have closure was brought up again. As usual, it attracted many readers' comments. I took the bait and posted a comment that reads:

I reckon Java should have closure. In terms of style, just make it the same as .NET (e.g. C#, closest to BGGA I guess). A great use case of closure is LINQ. This way, the argument about complexity/learning curve goes away since you can benefit in both worlds now. cheers romen

It was met with a reply which bears the typical trademark of 'go back to your own country' tone:

if you want .NET style closures, use .NET.

The full comment is available here.

In the real world, many people can speak more than one language, especially in this globalisation day and age. So it should be natural for developers to know more than one programming language and understand the differences of each computing world because each has its pros and cons, and each can learn from the other. Closure is one such example - it exists in many other languages and programming environments and now the Java community is debating its introduction to the Java land.

James Gosling, the creator of Java language expressed his support on embracing closure in Java. Introducing closure inevitably means introducing new language syntax, which are closer to functional languages. To me, functional languages are not so strange as we were taught Miranda in UNSW and I was exposed to Lisp as I was an Emacs user when programming in the Unix environment many years ago. Even to programmers who had never seen functional languages, it should not be such an alien concept - after all, mathimatical formulae are expressed in functional language, e.g. f(x,y) = 2x + y should look pretty straight forward to anyone who have passed high school.

So, just like in real life, with an open mind and some tollerance to differences, it is not hard to accept a 'foreign' concept to the Java world.

Sunday 6 July 2008

Anonymity on Internet

My usually pumped colleague recommended the movie Untraceable noting that geeks would love it. So I watched it on the flight and have to admit that I liked it - however corny the plot may be. I am no police, but I believe internet crime must be the easiest to solve because it is so easy to trace the activities at every layer of the network protocol stacks. With today's multitude of hardware and software based network management and monitoring tools, trying to stay anonymous on the internet is futile - the only way to stay anonymous on internet is either not to use it or use it very infrequently (which rules out anyone who blogs or maintains personal web sites) or manufacture your own NIC/driver.

As I browsed through every page of the Philippine Daily Inquirer by the pool this morning (what else can I do on a Sunday morning in the vibrant, steamy and materialistic Makati? ), I read a news about the demise of Chikatime.com blogger site (note, chikka in Tagalog means chit chat or gossip). The basic storyline is this: a guy opened a public blog called Chikatime to post negative comments and gossips about well known public figures of Philippines and earned some extra dough with it via Google Ads, while posing as girls on the blogger site. Meanwhile, his colleague 'ridge' found this out by installing network security/monitoring software on all workstations in the company (maybe ridge is an IT guy). So ridge dobbed him in to one of the public figures Jenni Epperson who had been humiliated by Chikatime and declared war on it. (It was a bickering contest between the mother hen and the ChickenTime.) So this time, mother hen Mam. Jenni bitch-slapped ChickenTime big time threatening to reveal his identity, photos, salary, credit card details and so forth. Finally, on July 4, 2008 Chikatime is shutdown complying to Ms. Epperson's demands.

This real-life saga is much more interesting than the movie. It was fascinating reading through the blog trail. While it reveals a lot of social and legal issues in the Philippines (such as rich vs. poor; spying on employees; stealing employee's personal information, incl. credit card details; etc.), my main focus here though is on the technical side. According to an episode of Insight on SBS about Stolen ID, it takes an experienced thief about 1-2 weeks to steal someone's identity using his/her internet profile as a starting point. Here, the 'identity' includes your real address, employment details, bank account details, etc. so that someone can pose as you to commit crime (e.g. financial fraud). If this thief is an insider (such as 'ridge' in this story), it takes even less time.

So, there is no anonymity especially on the internet. If someone dedicated wants to find you and has sufficient resources to do so, chances are that he/she will find you.

Disclaimer: no posts on this site have been produced or posted during business hours or using company resources. What? You mean that item posted at 10am on a Thursday? Well, ahem, I was travelling at the time and did not change my computer's timezone settings...

The Illusive SDP

The telecommunications industry is notorious for its (over)use of acronyms. Swimming through a sea of acronyms is a daily necessity working in the telco environment. Among the hottest swamp of acronyms at the moment is Service Delivery Platform (SDP).

In every telco tradeshows/conferences/junkets, SDP invariably pops up and people kept on boasting what wonders SDP can do to their business. Yet if you ask 10 people about what SDP is, you will get at least 11 different answers. Why? Because as of today, there is no official definition of SDP.

Looking up SDP in Wikipedia, the first thing it says about SDP is: There is no standard definition of SDP in the industry. Trying to find any SDP specifications from TeleManagement Forum (TMF), the closest thing you can get is a technical report (note, not a specification or recommendation) TR139 V1.0 - Service Delivery Framework Overview. At the end of the document (Appendix A), it says: Need to define what a Service Delivery Platform (SDP) is and how it relates to the SDF. The SDP Alliance offers nothing but piecemeal marketing slides and brochures.

You would think that by now telcos should have understood the nature of SDP and the fact that there is no official/standard definition of SDP. But no, vendors are muddying the water in this hot swamp. I have met several telcos who told me that there had been large IT or network vendors and their consultants claiming that those vendors' products/solution comply with the standard SDP specifications, and asked me how our products fit into this purported standard SDP architecture. I couldn't help telling them that labelling their so called SDP as 'standard' is like labelling a bottle of water Halal. In the end, they were happy to learn the truth.

On the other hand, I must hand it to the sales consultants from those vendors (many of them large and respectable, and therefore more harmful): it takes great courage and shamelessness to spin their own standards in this game.

Thursday 3 July 2008

Ouch! Ouch! Ouch!

Due to my usual forgetful nature, I forgot to pack my shaver again. Fortunately, I always have a spare Gillette Sensor Excel(TM) cartridge with me whenever I travel. So I shaved by holding up the tiny blade with my both hands...soon blood started dripping.

[Rewind to 10 hours ago]

On the flight to Mumbai, I was reading the Visual Studio Magazine, June 2008 issue. In it, there is an article on object validation, called Make Your Types Report Their State. It gives a good introduction of what object validation is all about and how to do it in VS.NET 2008.

[Fast Forward to this morning]

As I woke up early due to jet lag, I browsed the web (thanks to wifi broadband everywhere in Indian hotels). I came across an announcement about a Java object validation framework - iScreen 2.0.0, freshly out of the oven on June 28, 2008.

As in the VS Magazine article showed, in VS.NET 2008, a developer would have to sprinkle the Debug.Assert() statements everywhere in the code to achieve object validation. But in Java world, a dedicated framework has been created for free. iScreen factors the validation rules out of the core code into configuration files, making it easier to add and change those rules later. It also comes with a collection of pre-packaged validators, and plays well with other Java frameworks.

As an old Chinese adage says: if you want to achieve good results, you must sharpen your tools/weapons first (or something like that). Java has always been big on supporting and tooling frameworks. In some cases, too many. It looks like Microsoft again has some catching up to do.

My trusted Gillette Sensor Excel(TM) has done a decent job although without the support of a proper handle. Lucky for me, there is enough time between now and my next business meeting to allow the bleeding to stop.