Trinidad 0.8, gem extensions and database pooling 0

Posted by david

I think, the release of the latest version of JRuby-Rack was the perfect moment to do a new release of Trinidad and some new features. If this is the first time you bump into Trinidad, it's a Rack compatible server build on top of Apache Tomcat and release as a rubygem.

One of my main concerns about the project was that I wanted to build a lightweight gem and until now you had to download more than 5Mb with each release. The first step to avoid this was to split the gem in two, the main gem, trinidad, is now 12Kb, while the jars gem, trinidad_jars is just 3Mb, thus if I don't change the jars you'll just need to download 12Kb with each new release.

The second step is to stop adding features to the main gem. With each new feature that I wanted to implement more jar files were required and added to the package. Now Trinidad includes a little extensions api that allows to release features as little gems out of the core, you can find more details on the api into the wiki. So, from now I'll try to release new features as extensions and leave the core as tiny as possible.

The first extension that I've written adds support for database connection pooling through Tomcat and JNDI. The project is also hosted on github, and the installation and configuration are pretty straightforward.

Finally, an extra point. Of course, the coolest new feature is the Rails 3 support due to JRuby-rack already supports it, and, as you'll probably know, Rails 3 routes allow to split your application in several ones and route between each other. Just remember that Trinidad also allows you to run all those distributed applications within the same container with just a few configuration lines.

All in all, if you find a bug or you'd like to see other new features, please don't hesitate filing an issue in the project's tracker.

Have fun.

Loading several Rails applications into a single Tomcat container with Trinidad 0

Posted by david

Sometimes you meet that kind of people that complain about the lack of any feature in an open source project but they don't do anything to solve the problem. Last releases of Trinidad try the solve one of that complaints, so that people have one excuse less to use it :)

The goal of the project was pretty simple, allow to run a Rails application under Apache Tomcat without generating a war file in a more familiar "rails way". But that guy complained because he wanted to run several applications into the same instance of Tomcat, and actually he was partially right, Tomcat is a powerful application server and it can run several applications at once, thus, why don't allow to Trinidad to run several Rails applications?

After a few changes in its architecture, Trinidad allows to run as many Rails applications as Tomcat can support into the same instance. We just need add the application's context and their system path to the Trinidad's configuration file and run Trinidad with the option to read that file.

For instance, if we want to load three applications we had to add this nodes to the yaml file:


---
  :web_apps:
    :default:                                         # context path is '/'
      :web_app_dir: 'rails_apps/mock'
    :mock1:                                         # context path is '/mock1'
      :web_app_dir: 'rails_apps/mock1'
    :mock2:
      :web_app_dir: 'rails_apps/mock2'
      :context_path: '/mock2'

and run Trinidad with the configuration option:


$ jruby -S trinidad --config

That's it. Hope it will useful. Btw all the configuration options can be found in the Trinidad's wiki.

The Atom Exerciser on Heroku 1

Posted by david

From some time I've been getting some visits in this blog from Tim's page and I didn't know why, until this morning when I needed to use his Ape instance and I came across it was down.

I needed to use it from outside my private network, I thought on deploy it on Google App Engine, so I took the oportunity to move the repository to a more cool home, get rid of the old mongrel code and use a Rackable framework to manage its server and move its realeases to gemcutter.

All in all, after almost an hour trying to deploy it in GAE I realized I couldn't use it because its restrictions policy, so in the 10 minutes between I wrote these two tweets, I downloaded heroku gem, wrote a rack config file and deploy Atom Exerciser on Heroku. Enjoy it.

Tomcat-rails, develop rails app within tomcat 0

Posted by david

UPDATE: This project has been renamed and it's not longer mantained, please read this post if you want to know the reasons or just go to the new project web page.

This days I'm working every day with this stack, jruby+rails+tomcat. I was quite tired to have to pack the application and restart tomcat every time I wanted to test every slight change, so as a result, I wrote a script to use an embed tomcat within my application and this morning I wrapped it as a gem.

There is a lot of work to do but you can already download it from github.

It's usage is quite simple, just install the gem with jruby, go to the root directory of your rails app and run jruby -S tomcat_rails, or copy and paste this lines:


  jgem install calavera-tomcat-rails -s http;//gems.github.com
  cd myrailsapp
  jruby -S tomcat_rails

Any feedback will be really appreciated.

Rails template for Google app engine 2

Posted by david

I know, there is already too much buzz out there that talks about the new GAE's java support but I was sure I end up trying it.

I was following the Ola's post, it's quite simple to configure a rails project to deploy it on GAE, but I didn't want to repeat all those steps every time I'll deploy a new application, so I just wrote a rails template that adds all that stuff to my projects.

I'm waiting Jeremy'll add it to the templates repository, meanwhile you can grab it from my forked repository.

By the way, if you've already worked with rails templates you know they provide a git command that I'm not using in my template. That's because that command doesn't work outside the app root directory. I've already submitted a patch to the rails' lighthouse to solve it. Please vote it!!

Rails Hackathon in Madrid 1

Posted by david

Last month some friends of mine organized a great event called Monsters of Ruby. The topic was Ruby without Rails, and the challenge was mix random technologies and create a simple web app, my teammates and I suffered with SproutCore, Ramaze and Sequel.

Following its essence I'm organizing a new event called Rails Hackathon next February 7 in the 11870.com's office. The topic will be dive into the Rails core and send as patch as we can to the issue tracker.

Our office is not too much big so I've decided to close this event to 20 people, some of them have been already invited but there are some available places yet. If you are a Rails core contributor or you want to be and you enjoy diving in foreign source code send me a mail to calavera AT apache DOT org and I'll include you in the list.

Using Hudson as Rails CI server 3

Posted by david

For some time, Hudson has become my favorite continuous integration server. It's easy to configure and provides a handful of really interesting plug-ins. The only thing that I missed was the possibility of use Rake as a project build tool and thus I'll be able to take my java, ruby or rails projects into the same CI server.

Well, past weekend I had too much spare time so I decided to develop my first Hudson plugin and this morning I've released the first version of the Hudson Rake plugin.

Once you have installed Hudson you just need to donwload the plug-in and upload it from the Manage Hudson section:

When the plugin is avalable it detects your ruby instances installed from your PATH but it allows you to add other ruby or jruby paths:

Finally you just need to select the Invoke Rake option into the project configuration and select the tasks that you want to Hudson executes:

That's it, you are ready to go with Rake, Hudson and the Continuous Integration Game.

Usa ruby para testear tu código java 2

Posted by david

Aunque navegando por la web se pueden encontrar artículos sobre cómo usar rspec para testear código java y ya existe algún framework de bdd para java, desde hace unas semanas existe una librería que nos da las mejores herramentas de test que ruby posee para aplicarlas con nuestro código java.

JtestR es una librería que integra jruby con rspec, dust, mocha y ActiveSuport, y permite ejecutar nuestros test escritos en ruby con herramentas de automatización como Ant o Maven.

Para ejecutarlos con Ant es tan facil como incluir una nueva tarea en nuestro fichero de configuración:

<target name="test" description="Runs all tests">
  <taskdef name="jtestr" classname="org.jtestr.ant.JtestRAntRunner" classpath="lib/jtestr.jar"/>

  <jtestr tests="test/ruby"/>
</target>

Pero lo que más me gusta de este framework es poder usar rspec para testear mis clases java, un sencillo ejemplo podría ser este:

import java.util.HashMap

describe HashMap, "is empty" do
  before :each do
    @map = mock(HashMap)
  end

  it "should be empty" do
    @map.stubs(:size).returns(0)

    @map.should be_empty
  end
end

Una herramienta a tener en cuenta si, como yo, pasas el día entre código java y código ruby :-).

BDD & RSpec rulez 0

Posted by david

¿Por qué deberías pensar en usar BDD y RSpec?

Un ejemplo vale más que mil palabras

AtomPub, ruby y la api de 11870.com 2

Posted by david

Así se titula la charla que imparto en la segunda conferencia rails. Pretende ser una introducción a atomPub, la api de 11870 y todo esto mezclado con un poco de ruby.

Ya podéis descargar la presentación en formato pdf. Agradezco cualquier comentario, espero que sea útil.

Actualización: he subido la presentación a SlideShare para que se pueda ver desde aquí.

Conferencia Rails 2007 0

Posted by david

Este jueves comienza la segunda Conferencia Rails Hispana. Este año estaré hablando sobre AtomPub, ruby y la api de 11870.com. Cuando acabe subiré la presentación aqui para uso y disfrute.

ponente

Nos vemos allí.

Rails plugin: atom_pub_server 0

Posted by david

Update: he cambiado el repositorio y ahora el plugin se puede instalar desde GitHub:

   $script/plugin install git://github.com/calavera/atompub-server.git

Coincidiendo con el lanzamiento de la api de 11870.com tenía ganas de liberar un plugin para Rails que me ha ayudado a experimentar con AtomPub.

Como no soy muy original con los nombres lo he llamado atom_pub_server y básicamente sirve para empezar a implementar AtomPub dentro de una aplicación desarrollada con Rails. Ya que el punto de entrada del protocolo es su documento de servicio este plugin sirve para generar un documento de servicio a partir de los controllers de una aplicación. A partir de ahí, y gracias al genial soporte de REST por parte de rails y a alguna de las novedades de la versión 2.0 implementar un servidor de Atom Publishing Protocol con una aplicación rails es francamente sencillo.

Pero para ver como funciona el plugin lo mejor es ver un ejemplo. Empezaremos instalándolo en la aplicación desde el repositorio:

    $script/plugin install http://svn.thinkincode.net/rails/plugins/atom_pub_server

Supongamos que nuestra aplicación tiene dos controllers, uno llamado PostsController y otro llamado ServicesController. El primero será en encargado de gestionar una colección de recursos, así que le añadiremos el siguiente método:

    class PostsController < ApplicationController
      acts_as_collection :title => 'posts', :workspace => 'blog',
        :href=> 'http://myblog', :accept => Mime::ATOM_ENTRY
    ...

Al marcar este primer controlador para que actúe como una colección automáticamente se le añade un filtro anterior a los métodos de crear y actualizar un elemento. El método que invoca el filtro se debe llamar filter_content_type y los nombres de los métodos sobre los que se ejecuta se pueden configurar como variables de entorno, siendo por defecto create y update.

El segundo controlador será el encargado de generar el documento de servicio, así que lo marcaremos como tal:

    class ServicesController < ApplicationController
        acts_as_service_document
    ...

Finalmente, para que el controlador genere el documento de servicio solo tendremos que llamar al método "service_document" que le aporta el plugin dentro de otro de los métodos del controlador:

    def index
      render :xml => service_document
    end

y nos generará un xml parecido a este:

  <service xmlns:atom='http://www.w3.org/2005/Atom' xmlns='http://www.w3.org/2007/app'>
    <workspace>
      <atom:title>blog</atom:title>
      <collection href='http://myblog'>
          <atom:title>posts</atom:title>
          <accept>application/atom+xml;type=entry</accept>
     </collection>
    </workspace>
  </service>

Además, este plugin añade varios tipos Mime necesarios para la cumplir especificación de AtomPub:

    Mime::ATOM_ENTRY == 'application/atom+xml;type=entry'
    Mime::ATOM_SVC == 'application/atomsvc+xml'
    Mime::ATOM_CAT == 'application/atomcat+xml'

Para finalizar, he decidido sobreescribir uno de los nuevos helpers de rails, concretamente el que nos ayuda a escribir documentos Atom. El método original no permite añadir nuevos espacios de nombres siendo su llamada tal que así:

    atom_feed do |feed|
    ...

mientras que con este plugin podríamos escribir:

    atom_feed( 'xmlns:app' => 'http://www.w3.org/2007/app') do |feed|
    ...

Cabe decir que el método para sobreescribir 'atom_feed' sólo funciona con la versión actual de Rails (2.0RC) y posteriores. En el fichero README del plugin se puede encontrar una documentación mucho más detallada. Cualquier duda, sugerencia o mejora es bienvenida.

Validando feeds contra el w3c 1

Posted by david

Ultimamente he pasado demasiado tiempo jugando con los feeds de 11870, pero aunque tengo el proceso de creación bastante trillado y lo he dejado muy DRY nunca está de más validarlos.

El w3c tiene una web que te permite validar un feed alojado en una determinada url o pastearle el código que este genera dentro den un textarea. La principal pega es que si tu url es la de tu ordenador de desarrollo no la acepta y tienes que optar por la segunda opción.

Por suerte se les ocurrió liberar un api para no tener que estar copiando y pegando cada vez que queramos validar un feed que estemos desarrollando. Con esta api me he creado un script que indicándole el host y la ruta del feed, lo descarga y lo intenta validar contra el w3c, no es nada del otro mundo y seguro que es muy mejorable pero a mi me ha sido bastante útil.

Básicamente se trata de recoger el xml que genera el feed con la siguiente instrucción:

@response = Net::HTTP.get_response ARGV[0], ARGV[1], 80

Y enviarlo al validador:

v = W3C::FeedValidator.new
v.validate_data @response.body.to_s 

Una vez hecho esto podremos comprobar si el feed es válido con el método valid? y acceder a los mensajes a través de las variables errors, warnings e informations.

NOTA: El validador del w3c no funciona muy bien y de vez en cuando da algún error al validar, solo hay que insistir un poco hasta que pilla vuestro feed ;)

Crear fixtures fácilmente 2

Posted by david

Ruby on rails nos proporciona muchas comodidades a la hora de hacer desarrollos orientados a test. Quizá uno de los mayores inconvenientes sea tener que escribir nuestas fixtures, porque al trabajar con modelos algo complicados puede que no sean todo lo válidas que nos gustaría.

Fixturease es una gema que nos permite crear fixtures directamente a partir del modelo de nuestra aplicación.

Su instalación es muy sencilla:

sudo gem install fixturease

Una vez instalada, nos situamos en el directorio raiz de nuesta aplicación y ejecutamos el script fixturease.rb. Este, nos abrirá una consola que nos permitirá crear nuestas fixtures.

Supongamos que ejecutamos en esta consola el siguiente comando:

@david = User.create(:login => 'david', :password => 'pass')

Fixturease nos creará el fichero fixtures/users.yml con la siguiente entrada:

david:
  id: 1
  password: pass
  login: david
  created_at: 2007-01-20 21:40:23.250000 +02:00

Creo que es una buena forma de tener un poco más de control sobre nuestas fixtures y no tener que centrarnos en escribir un fichero yaml a mano.