const vs. readonly in C#

In c# what the hell is the difference between const and readonly?  I looked this up today and:

Here’s what I found.

Constants (const):

  • Are slightly less expensive to evealuate
  • Are static by default
  • Can be declared inside functions
  • Have gotta have compile time value
  • Are set at compile time inside assemblies that use them

Readonly (readonly) instance fields:

  • Must have set value by the time constructor exits
  • Are evaluated when instance is created

So I tend to use readonly fields if I ever think the constant will be referenced outside of my assembly.  Otherwise I’ll take the microsecond and use a const.

Linkedin oAuth desktop c# sample embedded webBrowser

I’ve created and uploaded some sample code for using Linkedin’s oauth library in a c# desktop app.  Faith Yasar’s c# code was my starting point.  A bit of a refactor of the oAuth librarie to include the oauth_callback parameter was needed, as well as code for displaying the login dialog.

Code can be found here in a forum post I made on linkedin.

The code contained includes a test harness as well as the oauth libraries for oauth login dance and Linkein API requests.  Oauth login is handled with an embedded webBrowser which is shown modally for the user to login.  Upon login completion, dialog will be closed and the token and verifier will be available from the dialogs property.

To use the code, simply Add your Linkedin consumer secret and Consumer key to the OauthLinkedIn.cs file:

private string _consumerKey = "ENTER_YOUR_CONSUMER_KEY";
private string _consumerSecret = "ENTER_YOUR_CONSUMER_SCRET";

Then you can make api calls following a few steps:

OAuthLinkedIn _oauth = new OAuthLinkedIn();
String requestToken = _oauth.getRequestToken();
_oauth.authorizeToken();
String accessToken = _oauth.getAccessToken();</div>

Hope that helps

RE: Climate jihadists want Canada to be embarrassed, but for what?

Dear Gary Lamphier,

A nerve is always struck when I read articles such as your “Climate jihadists want Canada to be embarrassed, but for what?” article appearing in the Edmonton Journal December 12th, 2009.
My annoyance isn’t related to my agreement or disagreement with some of your points; which as best as I can tell are:
a) the Mayor of Toronto should be more embarrassed about other issues,
b) that Canadians shouldn’t be embarrassed  about our environmental issues, and
c) that environmental summits are nothing but glorified holidays paid for by taxpayers.

My issue is with your strategy for making these points.

One wrong is not made right because you have a bigger wrong.  Similarly one wrong is not made right because someone else has a bigger wrong.  These arguments stopped making sense around the age of 8 for me.  So you pointing out that Toronto endured a garbage strike, and that China’s carbon emissions negate any progress we’ll make is irrelevant.  That is of course if I’m correct that you’re suggesting we shouldn’t be so embarrassed about our environmental leadership.

I’m also annoyed with your use of buzz words to invoke emotions to your readers.  Jihadist?  Do you know what this word means?  I suspect you do; actually I’m positive you do.  But I’m also positive that you know full well what your readers emotional response to a word that’s become so loaded will be.  I’ll mention that from my memory of Religious studies 100, “Jihadist” is a term used to describe a Muslim who favors or supports the jihad.  Jihad is an Islamic term, to represent a religious duty of Muslims.  But for most of us westerners, “Jihadist” = crazy fenatic who fly plains into buildings.  I imagine you’ll succeed in engaging readers with your use of this, but I fail to see the logic in comparing David Miller to a jihadist.  Maybe this Climate jihadist is a common term that I’m just unfamiliar with.  Are you simply saying that his duty is to advance environmental issues?

As an aside,  a personal pet peeve is the use of parenthesis to convey sarcasm.  So perhaps you’re use of this strategy got me off on the wrong foot.

I guess you’re asking why David Miller is embarrassed.  I can’t speak for him or any fellow Canadian, but I can tell you what I’m embarrassed about.

And I’m also a little embarrassed to say that I’m from a city where articles like yours make it to press.

Sincerely,

David Quail

Popular iPhone apps deliver value in 10s or less

I recently made an observation when taking inventory of the iPhone apps I have installed.

I noted that any app I use with any regularity will provide me with value in 10 seconds or less.  If it takes longer, I’d just as soon crack open the laptop and use the web/desktop version … or be distracted by some other app on my iPhone.  While there’s plenty of apps installed (at least 4 pages full), the only ones I use are Shazam, Mail, Contacts, Google Maps, Tweetie, Facebook, Weather, Showtimes …. all apps that I can get data from within 10 seconds.

It seems that the iPhone has tapped into our North American attention deficit selves.  I find myself busting out my iPhone any time I’m without stimulation … even when waiting for the traffic light to turn green.  The iPhone and it’s apps owe a lot of their success to an ability to fill the gaps in our day to day lives – it’s candy to the attention deficit.  And to me, there’s nothing better than an app that can entertain me in as little as 10 seconds.

Effects of alternative energy souces

I just finished reading Clean tech revolution.  Good book, excites me to think of technology advancing green initiatives and the role that a technologist can play.

When thinking about tapping into renewable energy sources – solar, geothermal, wind, tidal, etc. – I can’t help but wonder what the effects on nature will be when harvesting these natural sources.  I’m clearly a novice when it comes to geo-physics but you’d have to think these energy sources have huge roles in heating the earth, conducting air and ocean current, controlling weather, etc.  Would we be using so little of this energy that it doesn’t make a difference?  I’d love to read more research on this.

To me, it’s still pretty simple.  Humans demand WAY too much energy from the earth.  Whether you’re taking energy locked away in fossil fuels, or from wind blowing by your house to power an automobile … it’s going to have an effect on our ecosystem.  Ultimately, the only real clean watt is the Negawatt … the watt you don’t use.

oAuth authorization callback on the iPhone with WebView

There was a bit of chatter a while back about handling oAuth on the iPhone; in particular security balances sending a user to the website using Safari vs an embedded WebView.  Mike’s blog post discusses this so I won’t repeat, other than to say that I think either solution (webView or Safari) is open for spoofing.  An app developer could spoof an auth and grab creds in either case pretty easily … so I’ve chosen to optimize for user experience by implemented an oAuth webView for our app.

Here’s some of the relevant code for launching to an authorize website and handling the response.

* Our app uses oAuthConsumer library

* Our implimentation was against linkedin oauth which meant that I needed to pass the oauth_callback in our request token request by setting the oauth_callback parameter there rather than the authorize URL

In other words, our requestToken method looks something like the following:


OAMutableURLRequest                *request = [[[OAMutableURLRequest alloc] initWithURL: self.requestTokenURL consumer: self.consumer token:nil realm:nil signatureProvider: nil] autorelease];
 if (!request) return;
 [request setHTTPMethod: @"POST"];
 [request setParameters: [NSArray arrayWithObject: [[[OARequestParameter alloc] initWithName: @"oauth_callback" value: kLinkedInCallbackUrl] autorelease]]];
 OADataFetcher                *fetcher = [[[OADataFetcher alloc] init] autorelease];
 [fetcher fetchDataWithRequest: request delegate: self didFinishSelector: @selector(setRequestToken:withData:) didFailSelector: @selector(outhTicketFailed:data:)];

With the request token set, we’re able to pass this to the authorize url and it will return to our custom url

/*Create the request object for the linkedin URL*/


if (!_requestToken.key && _requestToken.secret) return nil;    // we need a valid request token to generate the URL

 OAMutableURLRequest            *request = [[[OAMutableURLRequest alloc] initWithURL: self.authorizeURL consumer: nil token: _requestToken realm: nil signatureProvider: nil] autorelease];

 [request setParameters: [NSArray arrayWithObject: [[[OARequestParameter alloc] initWithName: @"oauth_token" value: _requestToken.key] autorelease]]];

/*Load the webview with this request*/


[_webView loadRequest: request];

/*Check the response for a custom uri and redirect if it's set*/
- (BOOL) webView: (UIWebView *) webView shouldStartLoadWithRequest: (NSURLRequest *) request navigationType: (UIWebViewNavigationType) navigationType {
 NSData                *data = [request HTTPBody];
 char                *raw = data ? (char *) [data bytes] : "";
 NSURL* url = request.URL;

 if ([url.scheme isEqualToString:@"liconnect"]) {
 [_spinner stopAnimating];
 if ([url.resourceSpecifier isEqualToString:@"cancel"]) {
 if ([_delegate respondsToSelector:@selector(OAuthLinkedInAuthorizeViewFailed:)]) {
 [_delegate OAuthLinkedInAuthorizeViewFailed:self];
 }
 }
 else {
 [self dialogDidSucceed:url];
 }

 return NO;
 }

 if (raw && strstr(raw, "cancel=Deny")) {
 [self denied];
 return NO;
 }
 if (navigationType != UIWebViewNavigationTypeOther) _webView.alpha = 0.1;
 return YES;
}

/*Strip out the token and auth_verifier from the url*/


- (void)dialogDidSucceed:(NSURL*)url {
 NSString* q = url.query;
 NSLog(q);
 NSRange verifier_start = [q rangeOfString:@"oauth_verifier="];

 NSRange start = [q rangeOfString:@"auth_token="];
 if (start.location != NSNotFound) {
 NSRange end = [q rangeOfString:@"&"];
 NSUInteger offset = start.location+start.length;
 NSString* token = end.location == NSNotFound
 ? [q substringFromIndex:offset]
 : [q substringWithRange:NSMakeRange(offset, end.location-offset)];

 NSString* verifier = [q substringFromIndex:verifier_start.location+verifier_start.length];
 if (token&&verifier) {
 if ([_delegate respondsToSelector:@selector(requestTokenReceived:withVerifier:)]){
 [_delegate requestTokenReceived:token withVerifier:verifier];
 }
 }
 else
 {
 if ([_delegate respondsToSelector:@selector(OAuthLinkedInAuthorizeViewFailed:)]){
 [_delegate OAuthLinkedInAuthorizeViewFailed:self];
 }        }
 [self removeFromSuperview];
 }
}

You’re done.  You’ve now got your oauth_verifier and your access token all lined up to store away or make immediate calls to the api.

Baseball drama vs hockey action

Not too long ago I finished reading “Blink” by Malcom Gladwell Among the many things which stood out for me was the split second decisions required in sport. Because baseball allows for more analysis as the play goes on I believe it makes for a more mentally involved spectator experience than an action packed even such as hockey. At least using the “it’s a thinking game” argument helps me justify why I enjoy watching baseball so much.

When I was younger I played a lot of competitive hockey with some amount of success. I often remember sitting on the bench after scoring a goal, actually not able to remember the details of how the goal was scored, or the mental steps I took in positioning myself to score the goal. When I was playing my best, I felt like I was on auto pilot, simply relying on pure intuition. On the other hand, when in scoring slumps, I remember thinking long and hard about what to do on the ice. “Should I cross over and fill the left lane?” “Should I attack the net?” “Should I position myself behind the net?” It seemed as though the more I thought about what I should do, the worse I would play. Most sports are like this.

Baseball on the other allows more emphasis on analysis and positioning. Baseball allows for this since there’s more downtime between action where one can have more time to assess the situation. “The batter pulled the ball last time, so I’ll shade him into the hole,” “the count is 1-2 so I’m expecting a low ball so I’ll expect a ground ball”, “they’re down by 2 runs in the last inning so there’s no way they’ll steal second.” The list goes on and on.

I think that’s why baseball makes for a greater spectator sport. From the audience I can continuously run these scenarios. Time between each pitch I can guess what pitch is coming next, second guess the positioning of the second baseman. Hockey, for all it’s marvels, doesn’t allow me as much of an opportunity to question the positioning of the players.

Go Blue Jays …

Cruisecontrol and ant errors using gmail

Out of all the hours I’ve spent writing cruisecontrol, ant, and nant scripts, most of them have been troubleshooting mail tasks.

In attempting to set up cruisecontrol and ant projects for our iPhone application I ran across the following error when trying to send email using gmail:

Could not Connect to smtp host: smtp.gmail.com, port 587

Fixing this was dead easy after scouring the internet. It seems that neither ant or cruisecontrol play well with gmail over 587. Changing the mailport to 465 solved the problem:

Installing and Configuring Subversion

I also recently went through the process of installing and configuring subversion for a company.

Here were some of the notable steps

 

References:

 

Steps:

INTSTALLING AND MAKING SUBVERSION AVAILABLE

  1. Install subversion:
  • yum install subversion

 

  1. Install subversion mod_dav_svn plugin for apache 2.0 integration:
  • yum install mod_dav_svn

 

  1. Update the httpd.conf to load the mod_dav_svn.so module before any other subversion tasks. Add the following lines to /etc/httpd/conf.d/subversion.conf

    LoadModule dav_module         modules/mod_dav.so

    LoadModule dav_svn_module     modules/mod_dav_svn.so

            

    * If the firewall has www turned off on machine, you must enable this.  For example, in fedora, this can be done via: 

            System-Security Settings and Firewall -> Add www to allowed

 

CREATING THE REPOSITORY

The following steps all happen on the server.

1. Make the svn repository

  • mkdir -p /home/repos/svn/vrepos
  • svnadmin create /home/repos/svn/vrepos
  • cchown –R apache.apache /home/repos/svn

    * Note for SELinux / Fedora Core 3+ / Red Hat Enterprise users: 

In addition to regular Unix permissions, under SELinux every file, directory, process, etc. has a ‘security context’. When a process attempts to access a file, besides checking the Unix permissions the system also checks to see if the security context of the process is compatible with the security context of the file.

Assuming your linux box has SELinux enabled, to run Subversion under Apache, you have to set the security context of the repository to allow Apache access (or turn off the restrictions on Apache, if you think all this is overkill). The chcon command is used to set the security context of files (similarly to how the chmod sets the traditional Unix permissions). For example, one user had to issue this command

chcon -R -h -t httpd_sys_content_t /home/repos/svn

2. Set up a directory to import

– mkdir /home/repos/tmpsvn/vrepos

– cd /home/repos/tmpsvn/vrepos

- mkdir branches

- mkdir tags

- mkdir trunk

- mkdir trunk/ThirdParty

- mkdir trunk/Build – add build scripts to this folder

- mkdir trunk/Source – add Stargate and EcoTool folders to this

    

  1. Add info to httpd configuration so that apache can serve repository and it will be password protected:

 

<Location /vrepos>

    DAV svn

    SVNPath /home/repos/svn/vrepos

    SSLRequireSSL

    AuthType Basic

    AuthName "Subversion repository"

    AuthUserFile /home/repos/svn/svn-auth-file

    Require valid-user

</Location>

    

  1. Add the users to the password file:
    1. For each user:

    $$ ### First time: use -c to create the file

    $ ### Use -m to use MD5 encryption of the password, which is more secure

    $ htpasswd -cm /home/repos/svn/svn-auth-file davidq

    New password: ***** 

    Re-type new password: *****

    $ htpasswd -m /home/repos/svn/svn-auth-file rossa

    New password: *******

    Re-type new password: *******

    Adding password for user rossa

 

 

  1. Configure Putty to go against repository: https://surveyor.verdiem.com/vrepos

 

       
 

This is how the repository will look on the 

 

 

Installing testlink and JIRA

I just went through the process of installing testlink for internal test case management, so I thought my experiences were worth a blog post.

Testlink 1.7 is an online testcase management system. It allows you to manage the testing cycle by managing test plans, test cases, test execution results.

Test link is integrated with a php database and is easily installed on a lamp stack.

 

Great instructions and information on installing and managing testlink can be found in the following links or at the test link website. The details in these documents goes far beyond the details in this doc. I’ll just outline some of the specific settings I used when configuring testlink

 

Test link website: http://www.teamst.org/

 

Installation:

1. Install background services

* You need to make sure that the required services are installed on the machine. Mainly apache, mysql, php. Additionally, you need to install the php_mysql adapter. I needed to install this. In order to do so I actually re-compiled the php code this time including the mysql adapter. I recently found out that I could have just installed the mysql_php adapter using yum unlike what I had originally thought.

 

2. Tranfer the testlink installation zip and uncompress files into /home/repos/testlink

* The testlink zip file can be found on their website or at:

 

3. Point apache at the install directory by adding /etc/httpd/conf.d/testlinnk.conf with the following contents:

 

 

3. Change the owner of /home/repos/testlink to apache apache

– chmod apache.apache /home/repos/testlink

 

4. I never could actually get the security configurations correct with SELinux so that apache would actually serve the page. So I ….. disabled SELinux

– $ Echo 0>/selinux/enforce

To re-enable you’d add the following:

– $ Echo 1>/selinux/enforce

I also believe that when the machine is rebooted, seLinux may be re-enabled so testlink might just stop working.

 

5. Generate database tables and add data (create default or transfer from previous db)

– Go to http://localhost/testlink and login with admin admin (default which should be changed.)

– Follow the installation defeaults.

– All should go swimmingly and you’ve got a testlink instance up and running

– At this point you should be ready to add test plans, projects, test runs, users yada yada yada

 

JIRA integration

  • Note – as good as I think testlink is, it’s a bit week in it’s integration with bug tracking system. It essentially allows you to launch jira within testlink to create a bug, and then manually add the bug id to a test result.
  • Test results show the bugs attached to them and these bugs can be launched from within testlink (which is kinda nice). Also, when a bug is resolved, it shows up as struck out within the test execution record.
  1. Edit /home/repos/testlink/testlink_170/custom_config.inc.php file to specify that it is integrating with JIRA for bug tracking.

 

 

 

  1. Edit /home/repos/testlink/testlink_170/cfg/jira.cfg.php to point at the jira instance (database, database user, etc).

 

 

Restart httpd and you’re good to go.