Saturday, May 29, 2010

Software Engineering Craft (or Software Engineering as a performance art)

Experiment with full time students this summer to explore this topic.

In a language and framework of their choice, have students select a short project to build, ie a blog website, or twitter client mobile application. Include testing. In the first session, build the project. (Time it.) Repeat again. Repeat again. Repeat again. After each session reflect on what you learned. Was there insights about the IDE? Where there key command short cuts? Do your test cases get better from defects from previous sessions, or do they get worse because of short cuts? Is there an aspect of the technology that you are deficient in that requires additional practice? (Katana example) Look for trends across the student population.

Based upon trends across the student population, identify further areas of practice.

Try same experiment with paired programming.

http://github.com/edgecase/ruby_koans

Inspiration: improv - learning scene work or singing a song from scratch. Take an impossible task and break into small concrete steps. Slowly build upon the steps to reach the goal. Sometimes explore the concept of each step with positive and negative examples.

Inspiration: Katana for TDD

Inspiration: Learning to play the piano. Strength building exercises. The whole point of the exercise is to build up . Much like dance where there are patterns, technique and skill aspects to a class. The patterns make learning dancing fun and motivate the student to keep going. Playing a song is rewarding. Working on skill is tedious but makes the fun stuff more accessible and easier to accomplish.


http://rubyquiz.com/
Ruby Koans - http://github.com/edgecase/ruby_koans


Javascript learning - http://ejohn.org/apps/learn

Friday, May 28, 2010

Integrating openid, google apps, and ruby on rails

My university uses Google Apps for Universities. We wanted users to be able to authenticate to our rails application using their Google Apps account. Since Google Apps now supports openid, I thought that this would be really straightforward. A friend had just installed openid on his site and it was a breeze. I thought I would just install a few gems and get on with other rails development activities. I have no intention of becoming an openid expert. Here are the steps that I followed to get it to all work together.



Step 1) Enable Federated Login using OpenID on your Google Apps domain.

http://www.google.com/a/cpanel/{your-domain}/SetupIdp

Step 2) Download your needed gems

a) gem install ruby-openid
This is JanRan's ruby implementation of open id

b) gem install ruby-openid-apps-discovery
This is Google's extension of ruby-openid to work with Google Apps

c) gem install rack-openid
This is a rack wrapper around JanRan's open id

d) ./script/plugin install git://github.com/rails/open_id_authentication.git
This is Rails code to make integrating in with open id easier

e) Modify config/environment.erb and add this line
require 'gapps_openid'


Step 3) Add some code to your rails application.

 
class SessionsController < current_user =" @account.users.authenticate(params[:name]," required =""> ["http://axschema.org/contact/email", "http://axschema.org/namePerson/first", "http://axschema.org/namePerson/last"]) do |result, identity_url, registration|
ax_response = OpenID::AX::FetchResponse.from_success_response(request.env[Rack::OpenID::RESPONSE])
case result.status
when :missing
failed_login "Sorry, the OpenID server couldn't be found"
when :invalid
failed_login "Sorry, but this does not appear to be a valid OpenID"
when :canceled
failed_login "OpenID verification was canceled"
when :failed
failed_login "Sorry, the OpenID verification failed"
when :successful

email = ax_response['http://axschema.org/contact/email'].first()
first_name = ax_response['http://axschema.org/namePerson/first'].first()
last_name = ax_response['http://axschema.org/namePerson/last'].first()

if result.successful?
#Look up the user and if they don't exist then create the user
@current_user = ...
if @current_user
successful_login
else
failed_login "Sorry, no user by that identity URL exists (#{identity_url})"
end
else
failed_login result.message
end
end
end
end


private
def successful_login
session[:user_id] = @current_user.id
redirect_to(root_url)
end

def failed_login(message)
flash[:error] = message
redirect_to(new_session_url)
end
end





If you are still stuck, here are some other helpful links:

To understand open id: http://www.devx.com/opensource/Article/37692/1954?pf=true

To get google mail to work with rails plugin: http://stackoverflow.com/questions/2492043/ruby-open-id-authentication-with-google-openid

To understand all possible AX schema fields: http://www.axschema.org/types/#sreg

Discovering end points: http://groups.google.com/group/google-federated-login-api/web/openid-discovery-for-hosted-domains


Part 2


If you get a warning message like this
WARNING: making https request to https://www.google.com/accounts/o8/.well-known/host-meta?hd= without verifying server certificate; no CA path was specified.
WARNING: making https request to https://www.google.com/accounts/o8/site-xrds?ns=2&hd= without verifying server certificate; no CA path was specified.
WARNING: making https request to https://www.google.com/a//o8/ud?be=o8 without verifying server certificate; no CA path was specified.
Generated checkid_setup request to https://www.google.com/a//o8/ud?be=o8 with assocication AOQpcUfj9hGDs4DukDUrxhChnVBMbtoKAlXgvzQ1dp1L0yp6wCDxeFlx

The fix is pretty simple.
a) In your config/environment.rb file add the line
OpenID.fetcher.ca_file = "#{Rails.root}/config/ca-bundle.crt"
b) You'll need to get a ca-bundle.crt file. You should add in certificate authorities that you trust. If you are in a hurry, you can use the one in the ruby-openid-apps-discovery gem. Unpack it and find it in the lib directory. I copied mine to my application's config directory.

Sunday, April 4, 2010

Disappointment of arrival of my iPad

On the first day the iPad was available, I was one of the diehards to order it. I debated between picking it up or having it shipped to me. Instead of dealing with the hordes waiting in line at the Apple Store, I pictured myself at home, leisurely waiting for UPS or FedEx to arrive at my door. At the time, I didn't realize that April 3rd, 2010 was Easter weekend.

When I realized that I would be out of town for Easter, I began scheming how I could pick up the package first thing Saturday morning. When I had the tracking number from UPS, I discovered that UPS will call isn't open on Saturdays, besides UPS couldn't do anything since Apple hadn't shipped the product. When I received a FedEx tracking number for Saturday delivery, I was very excited, I would be able to show my iPad to my 20 relatives for Easter! I wondered if the change of shipper happened because of the rumored iPad production problems. Anyways, I was excited that I could work with FedEx to pick up my package. After arranging will call pick-up with FedEx, and getting the car fully packed up for our Easter trip, we drove to the FedEx warehouse. After waiting what seemed like eons, I had my iPad finally in my hands! Then I realized it felt awfully light. I opened it to discover not my iPad, but only an iPad case!

After my disappointment faded away, I realized that they had done split shipments. Instead of my iPad arriving on Saturday, as advertised, my iPad would be arriving on Monday.

I had looked forward to showing my iPad to all my relatives during Easter brunch. I thought it was brilliant that Apple was releasing it this social weekend. Now, I get to show all my relatives my empty case and tell a fun, yet disappointing story.

Update: My iPod arrived on Monday morning and it certainly is magical!

Tuesday, July 14, 2009

Legitimate cross site scripting (CSX) with AJAX

How do you do legitimate cross site scripting?
If you control the servers involved, this is how you can do cross site scripting with AJAX.

I recently came across a situation where I wanted to do an AJAX load from one server to another server. Internally to our campus, our students use a wiki and a ruby on rails web application. I wanted information contained in our rails application to show up on the wiki. My first impulse was to use jquery's load method, however, I received the following error:

Access to restricted URI denied" code: "1012

My first work around is just to avoid the AJAX load and use an iframe. However, inspiration hit me a few weeks ago and I tried a different solution. Since the AJAX load can retrieve information from the same website, maybe I should request a special url on the same machine and use apache to hide the fact that the content is coming from a different domain name. This can be accomplished with the apache ProxyPass command.

Let me give a concrete example. Say you have two websites: a static site that serves html pages through apache from the filesystem (http://static.sv.cmu.edu) and a dynamic site using an application server with a database (http://dynamic.sv.cmu.edu). You want some of the information from the dynamic site to show up on the static site. You want to allow users to add comments to a static webpage where the comments are rendered by the dynamic site.

Your first attempt might be:
$('#comments').load('http://dynamic.sv.cmu.edu/comments');
Which results in the error.

In static.sv.cmu.edu's httpd.conf file add the following line:
ProxyPass /comments http://dynamic.sv.cmu.edu/comments

Now from your browser window, test to see if you can access the dynamic data from the static machine: http://static.sv.cmu.edu/comments should give you the same information as would http://dynamic.sv.cmu.edu/comments

Now your AJAX code will work.

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
//<![CDATA[
$(document).ready(function(){
$('#comments').load('http://dynamic.sv.cmu.edu/comments');
});
//]]>
</script>


Tuesday, April 7, 2009

Guidelines for evaluating an Agile Maturity Model

When it comes to any Agile Maturity Model (AMM), it is paramount to start with the business value with respect to the framework. The framework should clearly identify the business and software engineering issues it is trying to solve.

The framework should be simple to understand. It's essence should be straightforward. Practitioners should be able to start applying the concepts and see progress. Days of training should not be a pre-requisite for adoption.

I am very reluctant to place any named method into different defined levels, unless the analysis is multi-dimentional. Let me be concrete. When an IBM employee identifies RUP as a Level 2 method and Scrum and XP as Level 1 methods, it is an open invitation for skeptics to find immediate cause to reject the maturity model as biased toward company loyalism. This is not to say that we should not compare and contrast different methods. Larman compares methods by ceremony and cycle while Cockburn scale's uses team size and criticality to determine a version of Crystal to use.

Wednesday, March 11, 2009

Extreme Programming: After 10 Years, Why Are We Sill Talking About It?

At the first keynote for SD West 2009 conference held in Santa Clara, CA, USA, Robert Martin (aka Uncle Bob) reflected on the history of the Agile movement, both what Extreme Programming and Scrum have done for the industry, and the need for Software Craftsmanship

Ten years ago, Extreme Programming had just arrived on the scene. People's reactions were either excitement or revulsion. Programmers who suffered under heavy weight processes rejoiced that they could get work done. The method has a high geek factor as it gave specific guidelines on programming and testing. This made it appealing to programmers but made it difficult for project managers or businessmen to get excited about it. Those who revulsed complained that without architecture and a thorough design, the software would become a mess. Because of these two reactions, Extreme Programming received a lot of attention.

After the birth of the agile manifesto at the Snowbird, Utah meeting, there were some unintended consequences. One was finding a better term to describe the new "lightweight" methods, and the term "agile" stuck. The success of adoption was beyond what they were expecting. Another interesting consequences was the new attention given to scrum.

Scrum is a near perfect subset of the Extreme Programming practices. It has the many of the same project management practices (Small Releases, Release Planning, Acceptance Tests, Whole Team, Product Owner) without the technical practices (Refactoring, Simple Design, Test Driven Development, Continuous Build, Paired Programming). In short, it doesn't "smell" of geeks. Scrum made agile palatable to business people. The scrum certification process allowed agile to cross the chasm as scrum became mainstream.

What got left behind were the engineering disciplines or "software craftsmanship." With scrum, you can turn the iteration crank very quickly, yet over time, the crank can get harder to turn as a mess begins to emerge. The nay-sayers of XP were correct in this regard, without replacing architecture and design with technical practices, you do get a mess. Now there is emerging talk of craftsmanship. People are using Katas to study how to write software. They write the same piece of software over and over again to learn technical mastery of software. Last Friday, the Manifesto for Software Craftsmanship was released. Robert ended his keynote with a plug for his Clean Code book and a green Clean Code bracelet that helps remind you to leave the world of code a better place by improving each module you come across.