April 9, 2009

Adding SOAP Headers to CXF Calls

Recently, I consumed a WSDL with Apache CXF that required authentication information to be placed into a SOAP Header rather than through standard HTTP authentication. This is all well and good, but I couldn’t figure out how to attach the headers to the CXF method calls. The authentication object had been generated by CXF, but there was no way to attach the object to the other methods.

After some research, I found the answer. Adding -exsh true to WSDL2JAVA updated the method signatures to include the header object as a valid parameter. If you’re cool like me and use the CXF Maven code generator plugin, the XML looks like this:

<execution>
<id>generate-sources-vixxi</id>
  <phase>generate-sources</phase>
    <configuration>
      <sourceRoot>target/generated-sources</sourceRoot>
        <wsdlOptions>
          <wsdlOption>
            <extraargs>
              <extraarg>-exsh</extraarg>
              <extraarg>true</extraarg>
            </extraargs>
          <wsdl>yourWSDLPathHere</wsdl>
        </wsdlOption>
      </wsdlOptions>
    </configuration>
    <goals>
      <goal>wsdl2java</goal>
    </goals>
</execution>



I verified this works with CXF 2.0.9 and 2.1.4. I haven’t tested it on any other versions, but I don’t see any reason why it wouldn’t work on 2.0.9+.

March 4, 2009

An Example of a Poor UI and Poor Customer Service

Or, perhaps more fittingly, why I am unhappy with Comcast.

Since I got back to Colorado from Hawaii in 2003, I’ve used, and been relatively happy with, Comcast broadband Internet. There have been issues, but nothing that has been so bad as for me to consider moving to another service.

Unfortunately, that changed last week.

Let me back up and say that I don’t often use my Blog to call out a company for something irritating (that’s usually relegated to Twitter). In this case, however, I feel it a good object lesson in how poor design coupled with horrible customer service can transform a (mostly) satisfied customer and cause them to look into other options.

What took place is pretty simple to understand. My wife and I share the account, and her email address is one of the six email accounts that I can have attached to our service. She decided she wanted to add another address. What she didn’t know, and what the UI didn’t tell her (in BIG RED WARNING LETTERS) was she was actually changing her email account. Without any “are you sure you understand what you are doing and want to do this?” type of dialog, her email address was changed and her previous account stopped receiving mail immediately.

When she realized what happened, she frantically clicked back to get her old address re-activated, but the UI continued to tell her the username was in use even though it had been deactivated.

She called me pretty upset, and I got on the phone with Comcast. They told me that they couldn’t do anything about the issue for a minimum of 30 days. When I asked them why, they told me that when an email address is deactivated, it gets placed into a “holding” status for 30 days to insure another person doesn’t take the alias and start receiving mail intended for another customer. This makes a lot of sense to me. The odd thing is that they couldn’t re-activate it for the same customer!

I told the CSR on the phone that someone should be able to quite easily login to their database and type something like:

update user set status="active" where username = "[Amber's username]";

and that, while I knew he couldn’t do it, someone with a shiny Comcast data-center badge could.

After much back and forth, he finally submitted an “IT” ticket for me. Since then, and his promise that this would be resolved in 72 hours (over a week and a half ago from today), I’ve heard nothing.

There are a couple of lessons here. The first is that it is obvious Comcast doesn’t get how important an email address is. I would have rather Amber lost her phone number than her email address. From our online banking to Facebook, it is extremely difficult to change an email address when you have no access to the old one. Most services send confirmation messages to the old email address. The CSR I spoke with and Comcast’s policies in general around this issue prove that, while they claim to be on the vanguard of Internet technology, they just don’t get it. At all.

Secondly, it is extremely easy to add UI confirmations so do it! There is no excuse for this type of oversight whatsoever.

Our current plan is to switch over to Qwest Fiber as soon as it becomes available in our area. Unfortunately, Comcast has lost our confidence.

January 14, 2009

Using Autocompleter.Local with Ajax Lists

The Autocompleter suite of functions in Scriptaculous are pretty nice. While they don’t solve every autocomplete problem straight out, they do provide a good starting point.

However, the answers to problems in Javascript are not always obvious. Despite some amazing support from Firebug, debugging is often difficult and tracing down problems can be rough.

Earlier this week, I ran into a very strange problem with Autocompleter.Local. I was designing a page that would query the server for a list of cities in a state and load that list into the Autocompleter. The catch was that the state could be changed at any time by the user, and the array containing the list of cities available would be updated asynchronously from the server. (While there is an Autocompleter.Ajax for automatic server updates, this assumes the autocompletion is done on the server side which I deemed too slow to be very functional in our case.) The specific issue I was having was that the city name was inserted into the target text field multiple times as the number of hits to the server for updated city lists increased.

I discovered, after looking over code in control.js, that the Autocompleter attaches event observers every time it is newed up. These event observers are difficult to remove manually because they pass in states of the specific object that are often no longer available. I had code that was doing something like:


[get list of city names for a state into cityNameList]
if(!autocompleter)
  autocompleter = new Autocompleter.Local('cityTextfield',
   'cityAutocompleteList', cityNameList);

but the the observers that the Autocompleter was creating were being piled up on each other every time I “reset” the Autocompleter to a new instance.

I discovered that the Autocompleter data is stored in the .options.array field. While it is not documented as part of the API, updating this array effectively updated the Autocompleter without adding new event observers. All I had to do was new up the Autocompleter variable once and then update this array field (directly; using dot notation) every time the data from the server changed.