TPR4: Dos Servicios Web, Por Favor

Quinn Madson, Lead Web Developer, University of Wisconsin–Milwaukee


The audio for this podcast can be downloaded at http://highedweb.org/2009/presentations/tpr4.mp3


[Intro Music]

Announcer: You’re listening to one in a series of podcasts from the 2009 HighEdWeb Conference in Milwaukee, Wisconsin.

Quinn Madson: Welcome to Dos Servicios Web, Por Favor. It's everybody talking about Web services. My name is Quinn Madson. I am Lead Web Developer for the University of Wisconsin-Milwaukee. I will be your shaved ape taking you through the jungle of Web services, as it were.

A little background about the presentation. It was originally created for an EDUCAUSE presentation and it was squarely focused at some of the management people that usually attend EDUCAUSE. Because at the time, when there was a call for proposals for EDUCAUSE, there was a lot of industry regs like Gardner and some others that were downplaying the importance of Web services or outright, like, misrepresenting, I thought, the benefit of them.

So I wanted to address that level of people and explain to them from a developer perspective why I thought it was important and the benefits you could get out of Higher Ed.

I've re-tooled it for HighEdWeb, obviously. It's a little bit more technical than it was previously. But I've left in some of that original management content because I think it's still important and relevant.

I'm sure you guys have heard about "Managing Up" or "Managing the Manager", and sometimes I've found that it's really important to be able to explain to management folks within your organization why a particular technology is really relevant to what you're trying to accomplish and what the benefits are other than what they're reading in magazines or reading on blog posts and things like that.

So with that, what I want to talk about is functionality fragmentation. And the way I look at Higher Education Enterprise Systems is, for the most part, we have really great systems, but they exist as fragmented functionality in their own little silos.

The University of Wisconsin-Milwaukee, up until a year ago, we had a separate system for mail and calendar. So if I want to do one function, I had to go to a completely different website, log in there again. If you want to do ERP stuff, for students to log in, they have to go to a different system. And you end up going to all these different places to accomplish something that should be relatively easy to do.

Along with that, there is also some confusion because now there is overlap in some of the functionality of those services that we provide. For example, in Zimbra, which is our new calendaring and email system, they're going to provide a Wiki. We use Xythos for file management, they're going to provide a Wiki. And we use CommonSpot CMS, and they're going to provide a Wiki.

So now you have different solutions to the same problem, and we have to figure out if any of those work for what we're trying to do or if we need to get a new system. So there's a little confusion as to how systems should be used and why. And that's what we're going to try to address with Web services.

So, this is kind of unattempted with portals in the past, but for the most part, I think that's been kind of a huge flop. I mean, the only portals I've really seen work relatively well are iGoogle and Netvibes, things like that that really allow users to develop content for that, to pull in their own information and to really customize it.

And a lot of times the portals that I've seen in Higher Education, they're pretty restrictive as to what the users can do, so no one ends up using them and you have them just sitting there collecting dust.

And when you think about learning styles, it's been accepted that some people are visual learners. Some people learn by doing, you know, some people are audio learners. And I think that there is really in information technology consumption styles. I might like to bring in my content this way and someone else might want to bring it in a different way.

For example, email. Some people have incredibly complex filter rules and an elaborate array of folders and everything gets sorted in based upon projects and who it's from, stuff like that. For me, I like to just put everything into an archive and then use search functionality that just pulls out what I'm looking for quickly. And if you have a product that has a good enough search, you can do that like Gmail, and some of the Zimbra stuff is pretty good with search.

But it doesn't mean that one way is wrong or one way is better. It's just the way that we work that all those different styles should be easy for users to implement.

Also, with budget cuts and people looking at how to do more with less, I think Web services is going to be a way that you can extend the functionality of your existing services and make a lot more usable for people and let them take more advantage of things that you already have.

So with that, this is the official definition from W3C. And what it says is, "Web services is a software system designed to support inoperable machine-to-machine interactions over a network."

Now, a lot of times, if you take out 'a Web service is' and show this definition to someone, they'll think you're talking about a chat program, because they don't really look at it as machine-to-machine. They look at it as, "Oh, I'm using a machine to communicate." I think this definition is kind of vague, but it's maybe one of the best that I've found.

If you try and do a Google define on Web services, you'll get a whole huge list of different definitions that vary in their complexity, and some of them actually have acronyms within the definition.

So if you're looking at it from a manager's perspective, when they're trying to figure out what a Web service is and they look for the definition and they're getting all tons of acronyms within that definition and now to have to look up those acronyms to figure out what I originally wanted to know, you can see how it starts to get confusing.

So, what I'm trying to get at is it's kind of hard to capture exactly what a Web service is just by trying to explain it to someone. And when you have this, it basically leads to fear because there's a lack of direction in that you can't go to some site and say, "How do I implement Web services for a Higher Ed institution? What are the six steps I can take to make this go incredibly easy?"

Because everyone has different systems that they're using and there's different ways to integrate those systems, so there's no really clear, definitive way on how to implement some of those stuff.

And with the lack of definition and the lack of how to do it, sometimes it leads to fear from the management end, and we don't get to implement some really cool things that we can advantage of.

Which leads us to: what are Web services? The way that I look at it, and the best way to explain it so simply, is to say that it can be glue between your applications or your services. You can start to blur the line of where one service ends and another one begins and take advantage of all kinds of information from a single spot.

Another good way that I've heard it explained is that you ask a question, answer a question. So with the Web service, I can call out to an LDAP Directory server and say, "I have this user QK Madson. Who is this person?" and it will return back as "Quinn Madson. He works in Central IT. This is his office. This is his phone number." And so that's another way to look at it.

But I think the best way to show what Web services are is to actually show them working, to have some way that you can show or demo it to people and show them different ways that you could implement this thing. So that is what I'm going to do right now.

I decided to make a video of this just because it keeps me a little bit more on track and stops me from blathering on about certain things. But this basically is Zimbra, which we call PantherLink. It's just our branded version of Zimbra email and calendaring. And this is what it would look like when a student walks in.

If I default right now, every student and instructor that logs into the system gets their class schedule displayed for them automatically. And that gets updated nightly if there's adds and drops and things like that.

That's done through Web services through PAWS, our PeopleSoft implementation. And it pulls in information about that class so you can see the location. Is Bolton B56, you can see the date that it occurs. You can see who the instructors are if there's multiple instructors. And if I click on that name, I can add them to my contact list if I need to get a hold of them.

And we've traded this thing called the Subscription Center, which is a Zimlet, which sits in this lower left corner of the screen. And basically a Zimlet is a piece of XML and Javascript that allows you to extend the functionality of the default interface. So what we did is we created this idea of Subscription Center where there's multiple calendars that students and faculty can subscribe to.

So for example, if I'm a School of Information Studies student, I can click onto the Subscription Center, I can see a list of events that are happening, and I can add this to my calendar. I want to make it orange. I click 'add'. And I get a couple of bubbles that pop up here explaining that that is being added in the background.

I can search. I can look for things that are occurring in our union. In our union, we have a bar in the basement called The Gas House, which is the first name that pops up. I can click on that, get more information. There is a couple of performances and trivia that's coming up. Say, for example, I'm interested in Studio Arts and Crafts, Pottery, Black & White Photography, click 'add', goes into the calendar.

We also set up a featured category, so you can click on that and you can see things that we're trying to push a little bit and get people to subscribe to and take advantage of. One of them is the weather, so you can get the weather on the top of your calendar everyday. So add that. And then the last thing we're going to do is navigate through the community calendars.

So in addition to university content that we have within the Subscription Center, we also have community calendars that might be relevant to students, faculty and staff such as the Green Bay Packers schedule or the Milwaukee Brewers schedule. Or you can add your Facebook accounts so events that your friends and family put on, you can add. And in this case, we're going to add movie releases.

OK. Great. So we close that, and shazam, we get this explosion of color on our calendar.

So, for example, now I can look at the weather, which is a daily note on the top of my calendar. If you double-click on it you get extended information about what's going to be happening. And if I hover over the dates, I see a list of other events that are happening on that day. If I close out of that, I can look at the School of Information Studies, which is an orange, and they happen to be throwing a conference on Wednesday in the same place, so there's going to be even more UW-Milwaukee people roaming the halls.

And you can put in all kinds of information. You can put links out to Web resources that people can use to register for an event, things like that. You can put a ton of information in there.

This is a movie releases that are coming out on Friday. People can look through and see if there's anything they want to go see. And on the bottom of that screen, we have our Studio Arts and Crafts. I can double-click on one of those events and see if 'Handbuilding in Clay: A Mesoamerican Tradition' is something I'm interested in.

And if this is something I want to add to my calendar, I can just change the calendar at the top, put it on calendar, and now it will sink to my calendar. So if I have a mobile device like an iPhone, something like that, it will actually pop up on my device and say, "Hey, you're late for this thing that you want to attend." So, that's one way that we're using Web services in the background.

The reason I like to use this example is because it shows it's very easy interface for students, faculty and staff to use to add all kinds of different calendars. In the background, we're using tons of Web services in order to pull it off.

So this is just a small example. It's written in ColdFusion, which I know not everyone uses.

But the good thing about ColdFusion is it's pretty straightforward. It's easy to learn. So if you have a programming background, you understand like functions, F10, loops and things like that, you really shouldn't have any problem looking at it and kind of understanding what it does. And I just want to kind of show it as a way that we're using Web services in the background.

So when a user clicks that 'add' button and they want to add that to their calendar, what we're doing in the background is we're calling to a function called 'subscribe', we pass in an 'off' token which comes from the Zimbra client itself, a target ID, a name, and a caller.

So the first thing we do on line 10 is check to see if they have a subscriptions folder, because we keep everything within the same folder hierarchy so it doesn't get messy. If they have one, we use it. If they need one, we create it.

The next thing we do down here is call out an SQL command that gets additional information about that item from the database. So I get the name, the description, and the ICS feed. And if you're not familiar with ICS feeds, it's basically just like an XML feed or an RSS feed. It's just formatted a little bit differently and it's specific to calendar information, and it's what most calendar products use.

So we grab that information. On line 32, we determine if it's an alias or not. One of the requirements from our users was that you could alias the same calendars in multiple places within the product. So for example, if I have some type of student movie releases, it will show up in the Student Section, but also maybe like an Arts Section.

So we determine if it's an alias and grab the proper ICS feed, which is being done right here just set to a variable. We update, again, with an SQL command into the database and keep statistics on what gets subscribed to so you can actually sort by popularity. So if someone's looking at this for the first time, they can see what's relevant to other people and it might be relevant to them as well.

The next thing we do is the 'cfsavecontent' tag, which basically just packages up everything within that tag into a variable called 'SOAP packet'. The 'cffile' put just executes or basically evaluates the variables, which are surrounded by pound signs in ColdFusion.

So if you have ever done anything with XML and SOAP before, this should look pretty familiar. This is my SOAP envelope. I have a header and I pass in their 'off' token, which came from the Zimbra interface itself.

The next thing I do is I create the body message. And within this body, it's a 'create folder request' tag and I specify the folder. The reason that's a folder is within the Zimbra interface, every calendar is a folder. It's just that it's a folder with a feed attached to it, which is what shows up in the user's view when they click on their calendar tab.

So we allow them to specify their name. We give to the feed URL from what we determined from before. This L is a target. We can specify a color. And this last thing just sets it so that this doesn't by default go against their free and busy times. So if I'm subscribed to a calendar of sports events, that's not going to go against someone's trying to schedule a meeting with me during that time.

And then we specify the views appointments. By default, the view is male. So if you didn't specify this, this would create a male folder with some type of feed attached to it. 

So we close out those tags. I run a quick, regular expression just to remove some white space. And then we do a 'cfhttp' request, which is basically just an HTTP request. It's just like you're hitting a webpage. In this case, it's hitting the Zimbra server in a specified URL that accepts these types of requests.

If you were in the first session today where they talked about URL headers, this should look basically familiar. Basically we're just telling the server that we're going to start to send it some information. And really the most important part is the bottom here. We're sending an XML message of SOAP packet that we just created.

So we send that off and we'll get a return back from the server saying if it was successful or not, which we in turn return back, and that can be used by your application that tells the user if it was successful or if there is some problem.

So, that's great and all if you already know how to create this XML. A lot of times, you've got to read the vender's documentation, look up their API, try and figure out how to do all that stuff.

And one of the things that we've fallen into with a bunch of different venders is that sometimes things are not documented very well, not documented at all, or it's very confusing as to what they're actually trying to get at with their documentation.

I have a quick example. And I hate to bang up on Zimbra since they've been giving me free food and drinks last night at the event that they had, but if we go to, like, this is their main documentation, which is just a plain text file, and if you go to line 1255 you see that they have stuff like this: 'Document me'. And this is what they give out to developers. So sometimes you kind of have to figure that out on your own and try and get there.

And I just want to show one of the great ways that I've been using it, which is... I'm going to turn on my work calendar here and pop up Firebug. And if I create an appointment within Firebug and click 'ok', you actually see it spinning in this console view. And what it tells you is exactly what's happening.

So you can actually use their own Web interface and use that to reverse engineer it, to figure out the XML that you need in order to do some of the integrations with the various products that are out there.

You can get all the headers. If you look at all this stuff--host, user agent, accept, keep-alive--I just stole all that and put it into that same request that we just saw on that function, you can actually view their post. So this is all their XML. You can see they're passing the Soft Token which is stored as a cookie.

And the important part is within the body, its pre-appointment request, which I'm going to copy. And you can see the response. So you can see if it was successful or not. In this case, it's spitting it back as JSON, and one of the cool things about the new editions of Firebug is that as a JSON browser you can actually just go right down the tree.

And if you're looking for something specific, you can get right down into the meat of it, which I really like. It makes it a lot easier. I'm just looking at all that text.

So now that you have the XML, the next thing that comes really useful is a good way to test it. And a lot of people use soapUI. I don't have a lot of experience with it. I've only used it a little bit. But what I've done is I usually just create my own testing tool within the language that we use.

And the reason I do this is because I can log in here with just a simple form, and now, every time that I make a request, it's going to attach that 'off' token. So I don't have to copy and paste the 'off' token or the username and password every time I'm trying to do something. That's kind of handled for me by my own code.

So I created this thing called Magic Soap Box, which you can basically copy and paste XML into. And this is just for our Zimbra implementation. I'm going to remove some stuff that's going to Air out here because I was skimping on my Air checking when I was building this, because I never thought I'd ever demo it to anybody.

[Laughter]

And I'm going to remove this timezone because there's an ampersand in it and that kind of throws it for a loop. And I'm going to change this name to 'Hello HighEdWeb'. And I can post this, and with any luck, will get this response. This is just formatted via Cold Fusion when it dumps out information, but you can see we've got a 'create appointment' response with XML attributes, passes back some IDs of what was actually created. We can then use that ID taken at database and say, "I created this appointment" and I can add metadata on that or other things like that that I might want to do.

Within my interface, I added 'you can toggle these debug dumps' so I can actually see what's being passed in. Because sometimes, when you pass in an ampersand, for example, it gets really weird as to how it actually gets interpreted. So you can view it right here and you can see the 'off' token is being passed in. And then within the SOAP body, it's exactly what I copy-and-pasted.

So, back to the presentation. Just roll back in building robots.

How do you get there? What we found was really helpful was to start off small, and there is a bunch of reasons why that was really helpful for us. Let me put this on fullscreen here.

One of the things we first created within Zimbra was a way to quickly look up information about a user, which was that LDAP example I had used previously. So basically what happens here is, I have a little interface where I can search our White Pages. So I can type in 'Madson', hit 'search', it returns back people that match within the university. I can click on that and I can see where they work, I can see what their office phone number is, stuff like that.

The really cool thing about how Zimbra works is it has a lot of cool drag-and-drop stuff, so if I don't know who this Matt Luba character is--he didn't put a signature in his email--I can just drag this over to the White Pages, like, oh, and it pops up who that person and I can immediately add them to my contacts for future use.

This is a really small example because all we're really doing is we're taking existing LDAP service and I'm just putting a Web services wrap around it so that I can call it from here. I passed at the information based on my search. That comes back with all their information.

So technically there's really nothing to it. But it showed our managerial people right away some of the things that we could kind of accomplish with Web services right from the get-go.

So, the nice things that this allowed us to do was start off small. It allowed developers to kind of get used to the technology.

I've never built Zimlets before so I had to get used to how their API is constructed, how you have to format your Javascript, because it's really object-oriented the way they do things and how I can get this all to work. Start off small and then test it, make sure things are working right, talk to the right people on campus to make sure you get sign-off from everybody, which is another big thing I'm sure you're all aware of.

And then once you start off on that small process, then you can start to scale it up, build bigger projects with bigger testing plans that affect more people and you have to get more people involved. So that was really, really successful for us.

And the important thing that we found was, a lot of times, when we build applications, you can hand something off to one person, they can build it, communicate with the client directly, and then there's no problems. But with a lot of these projects, you have to get a lot of different people involved. And we found was most successful was to use cross-functional teams.

[Laughter]

Quinn Madson: So, we had a group of people on campus called Integration Tech. And we had people from app developers to Web developers. We have integration architects, we have managers from different areas. We're bringing in people from the LDAP team or people from Security team when they're needed.

And that was really, really helpful because, you know, people have different experiences, different ways of looking at things, and you'll flush out a lot of bugs, a lot of security  holes, a lot of possible issues, issues that people on campus might have with particular things that you're doing because you have this group that has these different perspectives.

The other nice thing that having that cross-functional team allowed us to do was act as a consultancy resource for other people that we're interested in integrating different services, interested in various aspects of that. We kind of had this resource that we could use and people could come to us and ask questions and we could help them out with things that we had learned so that they don't fall in the same pitfalls that we had found.

And it just helped to foster communication between the various departments that are involved because there's all kinds of enterprise resources that have their administrators, then you have developers and sometimes when you want to quickly diagnose where a problem is or try and figure something out, having that network of people that should be contacted about that service was incredibly helpful.

The other thing that came up a lot with the manager-level people was the idea of security. You know, it's always someone's job to be looking at the security. I think sometimes they got more panicky than concern. And I try and keep people--you want to stay concerned about security, but you don't want that panic to overwhelm the people that are involved.

The great thing about using Web services is that it uses the Web. So a lot of the existing security infrastructure, you can just reuse. So things like SSL, basic OAuth when you're connecting to a service. For example, that's how Twitter runs their rest space Web services is you actually pass and using your password with basic OAuth, and it sets its own encrypted.

Which is weird because their log-in page isn't and LinkedIn doesn't have SSL, and that always has kind of blown me away, those services. Unless you specifically say you want SSL, you don't get it by default. So you can tell people that our Web services are more secure than you using Facebook or LinkedIn at work. Anyways.

Another thing that we used was, since it's app-to-app or service-to-service, you can employ IP-based restrictions because it's the service communicating, not the clients. So you can put that in and make sure you don't get DDOS'ed and things like that.

And there's other security options such as WSSC security blocks, which is basically an ID and token that you put within the XML packet when you send it. WSSC is a standard that I think they're trying to work on as far as getting it to be kind of the de facto standard for Web services. I know that PeopleSoft is trying to use it for theirs. But you can put in any ID and token as long as you're building the services and use that to authenticate where it's coming from.

So, the thing is, you have to let the people at the management level know that their security options are available, that it's up to the technology--you know, the technologists really deploy that functionality and make sure that it's all there so that they can rest assured that there is security that's being implemented with these and you're not blasting out personal information and other things like that onto the network.

If you have a security office, that was really helpful for us when they do risk assessments because that was something we can hand to the higher-ups and say, "This is the risk of it happening. This is the different options we have," and it's up to them to accept that risk if they want to go forward with it or not. It kind of takes it out of our hands and lets them decide whether it's something that's worth it or not.

And the other factor is, you may fail. And that's OK. I mean, it's kind of what Gerard was talking about at lunch is that failure isn't necessarily the worst thing that can happen.

The anecdote I like to use is that when I got out of high school, I worked as a cable guy for a while. And I had done hundreds of installs, put in RoadRunner, high-speed modems and cable boxes and things like that.

And I was in my own house and I was just doing a simple little outlet on the wall. And I was at a funny angle, and my drill just went right down the wall. It just screwed up the wall royally. And of course my father-in-law was there to see all this because, you know, it wouldn't just be enough for me just to mess up the wall. Someone had to actually see it.

And I was really upset because this is something I had done so many times that it should've been just second nature in order to put in a simple wall pod. And the thing he told me that really resonated was that the master craftsman isn't someone who doesn't make mistakes, it's someone who can recover from those mistakes and make it look like it never happened in the first place.

And I think that really applies to a lot of the stuff that we do with technology because, just because you fail, that doesn't mean that the whole endeavor was fruitless. A lot of times, even if you fail, you'll get some usable piece of code, you'll get some experience, you'll get something that allow you to keep going with what you're trying to accomplish, in this case Web services.

So you'll find little quirks within certain services and applications that have issues, you'll find other various things that you can apply as you go forward and build bigger and better services that your campus can use.

So the ability to adapt and overcome is huge. And it's not to say that planning should just be ignored because the ability to adapt is better. It's that you can plan for a lot of things, but when you're dealing with third-party venders and their solutions and how they want to use it, you have to adapt and try and figure out how the best way you can use it with your other infrastructure that you have in place.

So, what else could you do? Like, where else could you go with this? [Laughter] There is a big push right now to bring Web content to the desktop. If you look at things like Adobe Air, basically you can build these applications that use Web-based content but you can interact with the system tray or the dock, you can interact with the file system. You can do some really cool things and bring it right to someone's desktop.

Mozilla is doing a similar thing with Prism, which I think is currently in beta, where you can build basically desktop applications out of Web applications. And there is a lot of stuff you can do with social networks.

For example, that Subscription Center I was showing, you can bring in your Facebook contents into your calendar. So if students have stuff they're planning with friends and family outside the university, that's brought light into their calendar. And the reason that that's really important is because it allows students to really manage their lives better, especially for first-year students who are out on their own for the first time, don't have anyone kind of looking after them, you can look at your schedule and you can see this is when I have classes, this is when I have social things going on, this is where things are going on on campus that I can participate in.

And we hope it will lead to better attention because it will give students an opportunity to succeed.

So with that, questions? Discussion? Are there any right off the bat? Yes.

Audience 1: About security, did you ever hire an outside consultant, somebody to work with you doing those stuff?

Quinn Madson: No, because I really enjoy doing that. So a lot of times, I like to do that myself. And i just communicate with the security office and some of our network people when I do want to try anything like that just so they're aware of it, and they haven't had any problems with it. We've been really successful with security without adding holes, so we've kind of built a trust relationship with them of how we handle those types of issues.

But, yeah, you could hire someone if you wanted to and have them take a crack at it. We have a really good security office and they've given us a lot of resources and backing and help.

Audience 2: So would it be reasonable to say that the Firebug console could possibly develop the API for the software?

Quinn Madson: Absolutely. And that's the great thing is because with documentation, you never know. And if you are developer, you know that a lot of times that falls by the wayside. I'm as guilty as anyone else.

But the ability to reverse engineer is huge. And if you can use Firebug to do that... I mean, I found that awesome when I finally figured out that I could just do something in a Web interface and then reverse engineer and replicate it within an application. It was awesome. Yes.

Audience 3: [31:34 Unintelligible]

Quinn Madson: Yes. And if we had time, it was one of the things I kind of wanted to show, which is a little bit more advanced thing that we're trying to do. It's kind of in a pilot form right now. We built a homegrown tracking system for tutoring, mentoring, and advising on campus.

So basically it's a little kiosk that students can punch into, and then it has a background area where they can see who's there for service, and then they can add notes and custom fields and things like that. But the thing that we were able to do was create a scheduling component.

So if I'm working for a particular advising agency on campus, I can set my default availability and say that I'm available everyday from 8 o'clock until 4 o'clock generally. And then when someone goes to sign up, and they want to meet with me for whatever reason, they'll see today that I have no availability. And if they click on 'Thursday', they'll see that I have a couple availability blocks from 9 to 10, from 11:30 to 4.

And how that works is it actually looks at my existing calendar and I have these meetings set up right here. And what happens is it blocks that out from my available time with students. So every time that I have a new meeting, I don't have to go back and change my availability. It's just automatic because I'm using our calendaring system.

So we're doing stuff like that where we're trying to play off of things that are already in the system, read against that, and then block that out so students don't take times that you're meeting with someone else.

And it works as if it's tentative or if it's busy, so if someone schedules a meeting with you the last minute or if you just want to block it out because you have something to do, you just put that on your calendar and you don't have to worry about going into another system to change that information. It's automatically updated.

So that's another thing we're trying to do with Web services.

Audience 4: If you do it like that with the official API?

Quinn Madson: Yeah. It is one thing to worry about. We have done things with some products that didn't have an official API. We basically reverse-engineered it. And one of the things we did was we created a document and showed it to the client and said, "Hey, this is what we're doing. This is the best way we could configure to figure it out."

We contacted the vender and said, "Hey, what do you guys think about us doing it like this?" And they said, "Well, we're not going to change that. That's ingrained into the product and we're never going to change that." So they signed off on it. So as long as you are upfront about it and everyone's aware of it and you check out the vender, I think that's the best way to address the issue.

The API for Zimbra is official. It's just that sometimes it might be under-documented, or maybe I just don't understand of how it's documented. And using reverse engineering is, for me, a really great way to figure out how it's working and why and where I can add that functionality in, so...

Audience 5: Because lately we couldn't do text input. Suddenly it would show a test screen...

Quinn Madson: It's one of the things that... There's a whole bunch of things that we're trying to implement as a department as far as standardizing on a new ColdFusion framework and looking into unit testing for some of the applications that we're building.

It's one of those things, again, that falls by the wayside because projects have to get done. But it's one of the things we're focusing on and I want to get a better way of testing our applications. I'm using something like, there's CFC unit, an MX unit, and things like that for ColdFusion like there are for every other language, and we want to take better advantage of that. So just like you're saying, if something does break, you can rerun those tests to figure out exactly where it's breaking and then de-bug from there.

Audience 6: [35:39 Unintelligible]

Quinn Madson: Currently we're using an older version of Fusebox, which is not the model view controller version, but we're looking at Fusebox 5. We're looking at ColdBox. I've been looking at Model-Glue. And there's a lot of different frameworks that have their own benefits and drawbacks and learning curves and all that.

So it's something we're trying to evaluate when we have time between projects to try and figure out which--because we want to go at it together and not have six different frameworks that we have to worry about how to do it in this framework versus that one. We want to have something that everyone can use and take advantage of.

Audience 7: Just a question on how do you standardize for CMS and...

Quinn Madson: We try and standardize as best we can, so we primarily use ColdFusion.

The only times we end up deviating from that is when we're asked to support something that's someone bought and really didn't consult with us, so we'll end up taking that on and doing some custom stuff development for that. But for the most part, we pretty much use ColdFusion as our primary Web language.

We could talk about it later if you want to get more in-depth on some of the frameworks and share notes and stuff.

Anything else?

Well, thanks for coming. I hope you got something out of it. I hope you laughed a couple of times, at least.

[Laughter]

[Applause]