openSUSE:Appliances events workshop Nuremberg 2010 projects railsification

Jump to: navigation, search

Team:

  • Michael Calmer
  • Daniel Schmidt
  • Lucas Ocilka
  • Vladislav Gorobets
  • Gabi Mohr
  • Jozef Uhliarik
  • Cristoph Thiel

Railsify the registration controller

The goal of this task is to clean up the registration controller. This means, moving code blocks to places where they belong according to the conventios of rails. Rails defines a strict separation of Model, View and Controller. Helper methods are allowed in separate files, but methods that deal directly with data of a Model should be part of the very same whereas code that creates the output data has to be in the View.

First results for the railsification of the registration_controller in SLMS:

1. We have an example of using the view to build xml Files changed:

webapp/config/environment.rb
 config.gem 'builder'   added
webapp/app/controllers/registration_controller.rb
 list_subscriptions
 render 'list_subscriptions', :format => :xml
 instead of
 xml = build_listsubscriptions(subscr_list, result[:auth_user])
 render :xml => xml

File added:

webapp/app/views/registration/list_subscriptions.builder 

I.e. build_listsubscriptions from registration_controller_helper.rb isn't needed any longer.

2. We moved functionality from registration_controller.rb to model customer. These files are changed:

webapp/app/controllers/registration_controller.rb
list_subscriptions
functionality to build the list of subscriptions removed and moved to customer
webapp/app/models/customer.rb
def smt_subscriptions    added

Railsifying webservice routes

The registration (as defined by NCC) uses a static path for all queries and actions or special functions are passed as parameters together with all other registration data. This is not rails-like, as rails defines query paths to look like: example.com/controller/action .

It is not possible to change all installed systems to update to new query paths nor is it feasible to implement these changes in NCC. In order to railsify the registration internally we introduced a rails middleware that maps the current requests to rails-like routes. The middleware gets inserted between the Webserver and the rails application (SLMS in this case) and can hijack the request entirely, send an own response or just modify the request and call the underlying application with the changed request. In our case we just parse the parameter data and rewrite the request in order to map the already existing registration controller and its (to-be-defined) actions. So SLMS internally we can use all rails conventions and all requests look like standard rails requests and to the outside SLMS still behaves like a normal registration server.


The middleware that translates the requets to the registration controller looks like this:

class RegistrationTranslator
  ALLOWED_COMMANDS = %w[ register listparams listproducts de-register listregistrations listsubscriptions bulkop regdata ]

  def initialize(app)
    @app = app
  end

  def call(env)
    if env['PATH_INFO'] == '/center/regsvc' then
      reg = /command=([a-zA-Z0-9\-_]+)/
      action = env['QUERY_STRING'].scan(reg).flatten.first

      if ALLOWED_COMMANDS.include? action then
        env['PATH_INFO'].sub!('/center/regsvc', "/registration/#{ action }")
        env['REQUEST_URI'] = "#{ env['PATH_INFO'] }?#{ env['QUERY_STRING'] }"
      end
    end

    return @app.call(env)
  end
end

To make use of this middleware it needs to be inserted in environment.rb like this (after the config.gem section):

 config.middleware.use "RegistrationTranslator"

When run now, the middleware already translates the requests. But SLMS will render an error, as it does not yet know about the new routes. We map the route using the map.connect command in routes.rb:

 map.connect '/registration/:action', :controller => 'registration'

With all this setup the registration in SLMS will be transparently mapped from static paths externally to rails-like routes internally. All actions that are allowed for the registration still need to be exposed as own functions. This is part of the cleanup that alreay begun (see above).

We all learned a lot about rails conventions, separation of Model, View and Controller, middleware, the request model and find it worthwhile to merge our changes to the master branch of SLMS in order to allow future cleanup sessions if time permits. By this maintenance can be done by rails developers that are used to the rails conventions. If the middleware does not get included the methods in the controller can not be cleaned up properly.