Posted by: johnnywey | January 9, 2010

My Google Experience

I suppose it’s some sort of “rite of passage”, but I got pinged from Google about a month ago for a possible job opening. A Google recruiter came across my blog (very likely what you’re reading now) and thought my credentials and experience might be a good fit for a position at the office in Boulder, CO (that office, as far as I can tell, is mainly responsible for the Google Docs suite of products). While I’m pretty happy where I am, I felt very flattered they would feel that I could be a good candidate at a company whose hiring standards are the things of engineering lore.

The recruiter asked my permission to apply for the position, and the next email I received was that one of the senior engineers was interested in having a phone interview with me.

Let me back up and say that I was not sure what to expect. In my day-to-day projects, including those both both work-related and “for fun”, I typically spend more time playing with the latest technology than thinking about things like the efficiency of the Java Collections library. In other words, I’m very much a pragmatist rather than a theorist in most cases.

However, I decided to look at this opportunity, however it turned out, as an excuse to improve my theoretical skills and advance my effectiveness overall as an engineer. To that end, I delved back into discrete mathematics, algorithm analysis, concurrency issues, and overall performance making a conscious attempt to look at problems more like Google might (on a super-large scale).

I’ll talk about the actual interview below, but just the process of prepping for the experience was a huge boon, I believe, to my individual development as an engineer. In fact, I had such a good experience revisiting these topics that I have decided to both continue the process as well as begin looking towards starting a graduate degree later this year.

The interview itself went fairly well. As far as advice goes, I’d recommend anyone attempting to interview with Google refresh their algorithm analysis knowledge as well as spend some time on the more esoteric features of the platform/language in question. I had a question about Java inheritance which I answered incorrectly (I realized after the fact when I tried the scenario) simply because I rarely use inheritance in my day-to-day engineering (I prefer composition in most cases these days). However, I think my answer to the algorithm analysis question was pretty spot on albeit taking probably more time than I should have getting my head around the problem.

Despite not being picked up for the position, I’m still flattered that, less than two years after receiving my CS degree, I am getting interest from a company known for hiring only the best. It makes me believe that my career is on a good trajectory and gives me even more to look forward to in the future.

Posted by: johnnywey | November 4, 2009

Careful With Your Binary Resources!

Our production application stack has a fair amount of external service connections that require the use of certs for SSL security. We used to use a static reference (e.g. /config/certs or c:\config\certs for you Windows people) to locate the certificates, but this was always suboptimal as it made the application less portable. I finally got around to moving from the static reference and landing on Java jar introspection to find the file (using something similar to ClassName.getResource("/cert.pks");).

This conversion worked very well and everything seemed fine until the change got to our continuous integration (or CI) box. That machine, a Centos distribution, kept failing with the error Invalid keystore format when we tried to initialize the keystore in code. I spent hours trying to figure out the difference between my local machine (running OS X, which worked fine) and the CI box. I finally diff’d the cert file in src/main/resources and the resulting file in target/classes. I discovered that the two files were radically different.

Maven has a very cool feature that not only copies values from src/main/resources into target/classes and, ultimately, the resulting Jar file but also can substitute tokens in text files as part of the build (referred to as “filtering”). To enable this, all you have to do is add

<resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
</resources>

to your pom.xml file and you’re off to the races. However, Maven will process every file in the src/main/resources directory as part of performing this substitution. This normally wouldn’t be an issue, but certificate files contain some raw text and Maven dutifully filters them just as it would any resource. This caused a serious issue with the character encoding as Maven was writing out a file with a completely different encoding scheme than the file was created with. Basically, Maven filtering was corrupting our certs.

To fix this, I created a subdirectory off of src/main/resources (I called it binary) and added a manual exclusion in the pom.xml file. The resulting XML looks as follows:

<resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
                <excludes>
                    <exclude>**/binary/*</exclude>
                </excludes>
            </resource>
            <resource>
                <directory>src/main/resources/binary</directory>
            </resource>
</resources>

This worked perfectly. Hopefully, it helps some of you as well!

Grails is pretty awesome. Not only does it use Groovy as its main language, but it also provides nice DSL access to Spring settings.

Securing a website is something that can often be fairly complex and easy to get wrong. Grails provides a plugin for the state-of-the-art security model Spring Security (also called Acegi) (plugin can be found here).

Everything was all well and good until I tried to use two different security models simultaneously: a form-based login for human beings and an http basic authentication login for machines consuming an API.

This turned out to be pretty hard. The plugin requires setting the following in the resources.groovy file to work with basic authentication at all:

beans = {
  authenticationEntryPoint(org.springframework.security.ui.basicauth.BasicProcessingFilterEntryPoint) {
    realmName = 'Grails Realm'
  }
}

(The plugin is supposed to automatically do this by setting the basicProcessingFilter = true flag in the SecurityConfigure.groovy file, but there is a bug as of version 0.5.2 which is, as of now, the latest production release.) This worked for basic authentication, but would no longer redirect users to the form-based login.

Back to the drawing board.

What I discovered was that I could change between using the form-based login or the http headers authentication but not use them both. (I should clarify this by saying that I could shove the headers into the request and it would work, but a challenge response of 401 was not being sent back to the client which technically breaks the http authentication spec.) I found this thread (with contributions from the author of the Acegi plugin itself) but, while it pointed me in a nice direction, it didn’t answer the question fully. What I really needed was a way to use the URL to decide how to authenticate.

I finally discovered that the ExceptionTranslationFilter was not unique for the URLs I was using. In short, if the URL looked like: http://www.test.com/application/api/user/show/1, I wanted to use basic authentication and if the URL was http://www.test.com/application/user/show/1, I wanted to use the form-based authentication. The redirect is controlled by the ExceptionTranslationFilter and there was only one (so only one model would work at a time).

All I ended up having to do is create my own ExceptionTranslationFilter and wire it to the API URL. The final code in resources.groovy looks as follows:

import org.springframework.security.util.FilterChainProxy
import org.codehaus.groovy.grails.plugins.springsecurity.GrailsAccessDeniedHandlerImpl
import org.springframework.security.ui.ExceptionTranslationFilter

// Place your Spring DSL code here
beans = {
  basicAuthenticationEntryPoint(org.springframework.security.ui.basicauth.BasicProcessingFilterEntryPoint) {
    realmName = 'Grails Realm'
  }

  basicExceptionTranslationFilter(ExceptionTranslationFilter) {
    authenticationEntryPoint = ref('basicAuthenticationEntryPoint')
    accessDeniedHandler = ref('accessDeniedHandler')
    portResolver = ref('portResolver')
  }

  springSecurityFilterChain(FilterChainProxy) {
    filterInvocationDefinitionSource = """
         CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
         PATTERN_TYPE_APACHE_ANT
         /xml*/**=authenticationProcessingFilter,basicProcessingFilter,securityContextHolderAwareRequestFilter,anonymousProcessingFilter,basicExceptionTranslationFilter,filterInvocationInterceptor
         /**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
         """
  }
}

Now, visiting any URL that prefixed by a /xml/ will be a call to the basic authentication headers and every other prefix will be a standard form-based login.

Since I shaved a serious yak figuring this out, I hope it helps someone!

Older Posts »

Categories