avoiding SVN conflicts using svn:ignore

28 05 2009

I ran into this issue today: Dealing with conflictive files/directories in projects using Subversion. For example: Log directories and configuration files. But I’ve seen this problem before in my projects. I really like working in teams. But I also like having my own work environment.

I don’t really like sharing the database I use for development with other people. I guess it’s because of my experience and many past headaches due to teammates introducing conflicting changes (the system starts failing, ‘magically’)

This is a good practice suggested by Subversion: Use .tmpl files for conflictive resources in your projects. In my Rails projects, the conflictive file is usually database.yml -

My teams like to work with a development database in the Aycron office. I like to work with a local database. I believe it’s faster and safer. I save time by using my local MySQL database.

Here is what you should do, in order not to share the same database.yml:

1. Create your Rails project structure

[etagwerker@benteveo trunk]$ rails test-local -d mysql

2. Rename database.yml to database.yml.tmpl

[etagwerker@benteveo test-local]$ cd test-local

[etagwerker@benteveo test-local]$ mv config/database.yml config/database.yml.tmpl

3. Commit all your code to the SVN repository

4. Create your local copy from your template

[etagwerker@benteveo test-local]$ cp config/database.yml.tmpl config/database.yml

5. Ignore database.yml for the rest of your project

[etagwerker@benteveo test-local]$ cd config

[etagwerker@benteveo config]$ svn propset svn:ignore database.yml .

6. Commit the config directory

[etagwerker@benteveo config]$ svn ci

You’re done! Your teammates can do whatever they want with the database.yml, you can do whatever you want and there will be no conflicts over that file. Because it will never get committed to the SVN repository.





attachment_fu + ActiveScaffold 1.1.1: ‘content_type’ problem and solution

16 05 2009

I ran into this weird issue with attachment_fu and had no idea what was wrong with my code. I’m using ActiveScaffold and attachment_fu to manage my entities and images. The exception was not that useful and I only found the solution thanks to Diego, our Rails guru @ Aycron.

Here is the exception:NoMethodError (undefined method `content_type’ for “10.jpg”:String):
/vendor/plugins/attachment_fu/lib/technoweenie/attachment_fu.rb:294:in `uploaded_data=’
/vendor/plugins/active_scaffold/lib/attribute_params.rb:106:in `send’
/vendor/plugins/active_scaffold/lib/attribute_params.rb:106:in `update_record_from_params’
/vendor/plugins/active_scaffold/lib/data_structures/action_columns.rb:68:in `each’
/vendor/plugins/active_scaffold/lib/data_structures/action_columns.rb:55:in `each’
/vendor/plugins/active_scaffold/lib/attribute_params.rb:49:in `update_record_from_params’
/vendor/plugins/active_scaffold/lib/attribute_params.rb:71:in `update_record_from_params’
/vendor/plugins/active_scaffold/lib/data_structures/action_columns.rb:68:in `each’
/vendor/plugins/active_scaffold/lib/data_structures/action_columns.rb:55:in `each’
/vendor/plugins/active_scaffold/lib/attribute_params.rb:49:in `update_record_from_params’
/vendor/plugins/active_scaffold/lib/actions/create.rb:73:in `do_create’
/Users/etagwerker/.gem/ruby/1.8/gems/activerecord-2.0.2/lib/active_record/connection_adapters/abstract/database_statements.rb:66:in `transaction’
/Users/etagwerker/.gem/ruby/1.8/gems/activerecord-2.0.2/lib/active_record/transactions.rb:80:in `transaction’
/vendor/plugins/active_scaffold/lib/actions/create.rb:72:in `do_create’
/vendor/plugins/active_scaffold/lib/actions/create.rb:28:in `create’
/Users/etagwerker/.gem/ruby/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:1158:in `send’
/Users/etagwerker/.gem/ruby/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:1158:in `perform_action_without_filters’
/Users/etagwerker/.gem/ruby/1.8/gems/actionpack-2.0.2/lib/action_controller/filters.rb:697:in `call_filters’
/Users/etagwerker/.gem/ruby/1.8/gems/actionpack-2.0.2/lib/action_controller/filters.rb:689:in `perform_action_without_benchmark’
/Users/etagwerker/.gem/ruby/1.8/gems/actionpack-2.0.2/lib/action_controller/benchmarking.rb:68:in `perform_action_without_rescue’
/usr/local/lib/ruby/1.8/benchmark.rb:293:in `measure’
/Users/etagwerker/.gem/ruby/1.8/gems/actionpack-2.0.2/lib/action_controller/benchmarking.rb:68:in `perform_action_without_rescue’
/Users/etagwerker/.gem/ruby/1.8/gems/actionpack-2.0.2/lib/action_controller/rescue.rb:199:in `perform_action_without_caching’
/Users/etagwerker/.gem/ruby/1.8/gems/actionpack-2.0.2/lib/action_controller/caching.rb:678:in `perform_action’
/Users/etagwerker/.gem/ruby/1.8/gems/activerecord-2.0.2/lib/active_record/connection_adapters/abstract/query_cache.rb:33:in `cache’
/Users/etagwerker/.gem/ruby/1.8/gems/activerecord-2.0.2/lib/active_record/query_cache.rb:8:in `cache’
/Users/etagwerker/.gem/ruby/1.8/gems/actionpack-2.0.2/lib/action_controller/caching.rb:677:in `perform_action’
/Users/etagwerker/.gem/ruby/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:524:in `send’
/Users/etagwerker/.gem/ruby/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:524:in `process_without_filters’
/Users/etagwerker/.gem/ruby/1.8/gems/actionpack-2.0.2/lib/action_controller/filters.rb:685:in `process_without_session_management_support’
/Users/etagwerker/.gem/ruby/1.8/gems/actionpack-2.0.2/lib/action_controller/session_management.rb:123:in `process’
/Users/etagwerker/.gem/ruby/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:388:in `process’
/Users/etagwerker/.gem/ruby/1.8/gems/actionpack-2.0.2/lib/action_controller/dispatcher.rb:171:in `handle_request’
/Users/etagwerker/.gem/ruby/1.8/gems/actionpack-2.0.2/lib/action_controller/dispatcher.rb:115:in `dispatch’
/Users/etagwerker/.gem/ruby/1.8/gems/actionpack-2.0.2/lib/action_controller/dispatcher.rb:126:in `dispatch_cgi’
/Users/etagwerker/.gem/ruby/1.8/gems/actionpack-2.0.2/lib/action_controller/dispatcher.rb:9:in `dispatch’
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/rails.rb:76:in `process’
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/rails.rb:74:in `synchronize’
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/rails.rb:74:in `process’
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:159:in `process_client’
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:158:in `each’
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:158:in `process_client’
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:in `run’
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:in `initialize’
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:in `new’
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:in `run’
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:268:in `initialize’
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:268:in `new’
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:268:in `run’
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel/configurator.rb:282:in `run’
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel/configurator.rb:281:in `each’
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel/configurator.rb:281:in `run’
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/bin/mongrel_rails:128:in `run’
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel/command.rb:212:in `run’
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/bin/mongrel_rails:281
/Users/etagwerker/.gem/ruby/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:489:in `load’
/Users/etagwerker/.gem/ruby/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:489:in `load’
/Users/etagwerker/.gem/ruby/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:342:in `new_constants_in’
/Users/etagwerker/.gem/ruby/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:489:in `load’
/usr/local/lib/ruby/gems/1.8/gems/rails-2.0.2/lib/commands/servers/mongrel.rb:64
/usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require’
/usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require’
/Users/etagwerker/.gem/ruby/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:496:in `require’
/Users/etagwerker/.gem/ruby/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:342:in `new_constants_in’
/Users/etagwerker/.gem/ruby/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:496:in `require’
/usr/local/lib/ruby/gems/1.8/gems/rails-2.0.2/lib/commands/server.rb:39
/usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require’
/usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require’
/script/server:3
-e:2:in `load’
-e:2

My code was organized so that a Page entity had one Image entity. The data structure was correct. The problem was in my controllers. images_controller was fine. I could check that by uploading images using that particular controller. The problem was with pages_controller. pages_controller uses images_controller to create/edit pages and their associated images.

pages_controller was missing a few lines of ActiveScaffold configuration. Particularly the lines associated with multipart forms. See ActiveScaffold:: create API.

The solution is to add the following lines to the pages_controller ActiveScaffold configuration:

config.create.multipart = true
config.update.multipart = true

That did the trick. I’m writing this down here so that I don’t forget the solution. Oh and maybe someone else will find this useful, if they ever run into such a useless exception message.





web applications stress testing with JMeter (part 2)

13 05 2009

Here are a few notes about executing the stress test:

  • If you are using only one computer, remember that you are using only one CPU, one memory, one internet connection and one operating system. So I would advise not to do many things at once in your computer while you test (for example, don’t download that torrent!)
  • Also, I would not to do any CPU-intensive activity while stress testing my web application
  • Each single test may fail. I didn’t have that problem often, 1 out of 12 tests. But one of them did not finish correctly. You can see this by comparing the total requests per test (compared to other tests you performed) – For example, your internet connection might unexpectedly go down and make your test useless
  • Have a good connection. You should properly measure the delay you have between your computer and the server.  The delay I had between my client and server was minimal

I ran a set of tests to have a base set of results. The initial set of results was not good (though I was expecting this). I noticed there was a high load on the database. Mongrel was not taking most of the server resources, MySQL was.

With our team, we decided to implement a mongrel-level cache to reduce database access and improve performance/throughput.

The second set of tests showed a big improvement. Performance improved a lot! The cache reduced the load on the database. This was very noticeable. We applied the cache to the most visited sections. To know which were the most visited sections, we used historical Google Analytics data from the project.

The set of tests didn’t vary on the client side. I simulated a load of 100, 200, 500, 750, 900, 950 and 1100 concurrent users.

The result improvements were 3 times better (the lowest), 15 times better (the highest) and  11 times better (the average)

To sum things up, JMeter is a very useful tool for stress testing web applications. You will have to read their documentation to understand the graphic results (numbers are shown but units are not always shown).

If you haven’t developed any performance-related code (eg. cache) for your application, run a first set of stress tests before you do. This will give you a base for improvement.

Develop your performance improvements, test them, make sure they are working as expected (eg. cache invalidation working properly) and then run your second set of tests. You will definitely make a difference on the throughput of your application. If not, you will have to keep making improvements until you see the results.

Have fun!





web applications stress testing with JMeter (part 1)

27 04 2009

Before starting to stress test my application, I had to determine which was the best option: SLAMD (http://www.slamd.com) or JMeter (http://jakarta.apache.org/jmeter).

Even though I had experience with SLAMD, I knew that it was more complicated to install SLAMD than JMeter. JMeter is a ‘simple’ client that stresses different types of servers with no need to install anything in the server. SLAMD is a complicated set of components (client/server). However, this complexity provides way more information about your server’s performance.

Due to time restrictions, I decided to go with JMeter to test the overall throughput of my web application. If I remember correctly, if I had chosen to test using SLAMD, I would have had to install a SLAMD client, a SLAMD server and resource monitors in the target web application box. For now, I think JMeter will serve its purpose and give me an overall idea of my web application’s performance.

According to this page: http://wiki.apache.org/jakarta-jmeter/HowManyThreads, I can simulate 10,000 concurrent users hitting my web application. That sounds like a decent initial goal. In the future, I’d love to test simulating 100,000 concurrent users. But I don’t think my web application will get that traffic nowadays.

In the future I will definitely need to use a SLAMD testing environment.

As (almost) every Java desktop application, it is not pretty. But it is easy to use. If you follow this manual: http://jakarta.apache.org/jmeter/usermanual/build-web-test-plan.html - As it is Java, you can run it anywhere you have Java installed (and that’s what I love about Java)

So, here are the instructions to run it in a Mac:

1. Download the JMeter from here: http://jakarta.apache.org/site/downloads

2. Unzip it

3. Fire up a Terminal and go to the unzipped folder

4. Make bin/jmeter.sh executable

[etagwerker@benteveo bin]$ sudo chmod +x ./jmeter.sh

5. Run jmeter.sh

[etagwerker@benteveo bin]$ ./jmeter.sh

By now you should see a GUI window that enables you to create the test plan you want. Try to make the plan realistic. No user will ever go to every single page of your site. They will get to the home page, they will go to a few sections, they will maybe search for a keyword and they will check out the content they find.

You should write a test that is simple. Consider that the path that you define will get executed for 100, 1,000 or 10,000 times. For this, all you need to know is in the JMeter user manual.

This is what I did:

1. Added a Thread Group, which serves as the base for everything else

2. Added HTTP Request Defaults, which serves to configure your base URL (eg. http://google.com)

3. Added 8 HTTP Requests, which simulates the traffic from all the concurrent users

4. Least and most important, add a Graph Visualizer! This will show you the results you are looking for

This article should serve as a basic introduction to stress testing web applications with JMeter.

In the next post, I will write about what I learned after running the tests. I am currently running stress tests varying the threads in my Thread Group, to simulate different loads (100, 200, …, 1000 concurrent users)





developer testing vs. tester testing

14 04 2009

A developer testing will never be as good as a tester testing. I know that developers can be great testers. And maybe testers can be great developers too. But developers testing the same features they develop will never be as thorough as a tester testing features he knows nothing about. A tester knows how to ‘break’ software.

That’s why I believe that features should be tested by at least one person, other than the developer, before they reach the client. Developers assuming the ‘tester’ role can be really good at finding bugs. But they must have no mercy. They have to keep in mind that ‘successful’ testing finds bugs. And if they do, I’ll be happy.

The main difference between each person testing is that the tester (who did not build the feature/project) will have no mercy. The tester won’t care for what is inside the code. The tester will know the spec, will set up the environment and will test away. It will definitely find bugs, it will try many ways to make the system crash. The testing will be creative (it must be creative) and it will be successful once it reports many bugs.

The developer, as much he tries, will have mercy. After all, it is his production, and he will assume things that the tester won’t. The developer will assume that people will be nice. That the user won’t ever do the things that the tester imagines. And there is where the error lays. The predisposition of the developer and the tester are different and that is what makes me prefer tester testing over developer testing.





annotate-models for practical rails

26 03 2009

Tired of going to schema.rb to find your table structures information? Get the annotate-models plugin for documenting your model classes! 

I just found the annotate-models gem the other day, after reading a chapter of this book: 

Enterprise Recipes with Ruby and Rails

Also, I found this clear explanation about the usage of the gem:

http://ruby.geraldbauer.ca/rails-annotate-activerecord-models.html

It’s pretty amazing. It’s also pretty weird that it’s not inside Rails already. Maybe it is? Anyway, if you are tired of going to your schema.rb to check out your tables structures, you should read about this plugin and use it. It does exactly what you want it to do. It adds documentation to your model classes about your tables structures.

For someone coming from the Java world, used to having Javadoc in each one of the business/model classes, it is awesome to have. It makes you feel like just the syntax changed, when you look at your model classes.





deliverability 101

17 03 2009

I have been learning a lot about a very interesting subject: deliverability. Ever since I started working on this project which includes a huge mailing list, I feel like my knowledge of ‘how mail gets to your inbox’ has increased considerably. It sounds like a simple matter, but there is a lot to it. Mostly because of people who love to sell medicine or other products you don’t really want (AKA spammers)

This project integrates with Lyris List Manager, a pretty awesome tool for managing your mailing lists. I say ‘pretty awesome’ instead of ‘totally awesome’ because I’m still waiting for them to fix a couple of major bugs that are stopping our project. When they do (this week?) I’ll change my opinion. 

However, this tool gives you great visibility over the results of your mailings. You can see if they received the message, if the SMTP server blocked your message, if the address doesn’t really exist, if the ISP of your subscriber doesn’t really exist, if they clicked the SPAM button, if they unsubscribed and when they did and probably a whole lot of other things that I haven’t seen yet.

Here are a few reasons why your message would not get to someone’s inbox:

1. You have the address wrong (the account doesn’t really exist at the ISP – eg. etagwerker@domain.com, etagwerker isn’t a user of domain.com anymore)

2. The ISP doesn’t really exist (I’ve seen every way someone can misspell Yahoo – eg. Yaoho, Yaoo, Yhaoo, Yaho, ayhoo – amazing but real)

3. The ISP has some strong content blocker (some ISPs do not like when you add ‘Free!’ to your subject) and the subscriber hasn’t added you to his/her contacts list yet

4. The ISP decided to defer your message for later, because you are probably sending too many emails in a period of time (Yahoo is a specialist on this matter)

5. The ISP woke up cranky and decided that it didn’t like an image or some content in the body of your message (seriously, different days have different results and the only thing that changes in my mailing is the content)

Those are a few reasons why mail won’t get to someone’s inbox. There are a lot more, but maybe this article serves as an introduction to the huge deliverability area of knowledge.





ImageMagick + rmagick + unknown format: png

24 02 2009

Recently I ran into a problem with ImageMagick, rmagick and my Rails application. Somehow my environment was messy and it included varied versions of ImageMagick. This is what I did to solve the problem:

1. Removed all installations of ImageMagick

There was one version that was compiled and installed. I uninstalled it doing this:

# go to wherever you have your make file

cd /usr/local/ImageMagick-6.4.9-4

# run make uninstall with sudo, this rollbacks make install

sudo make uninstall

There was another version that was installed using yum. I uninstalled it doing this:

sudo yum erase ImageMagick

2. Removed all ImageMagick directories from my environment, like this:

I had to repeat the following step a couple of times with different directories:

# you must have root privileges

# this updates the filesystem database to use locate

updatedb

# this finds whatever files/directories have ImageMagick in it

locate ImageMagick

# this gets rid of the ImageMagick library (which wasn’t getting used, anyway..)

sudo rm -r /usr/local/lib/ImageMagick-6.4.9

Basically I got rid of all the unnecessary ImageMagick directories (since I had already uninstalled ImageMagick)

3. Installed libpng using yum:

sudo yum install libpng

4. Installed ImageMagick-devel using yum:

Before I did this, I tried to install rmagick’s gem. (just for the fun of it)

That didn’t work because rmagick didn’t find ImageMagick in the environment.

sudo yum install Magick-devel

5. Installed rmagick

sudo gem install rmagick

6. Restarted my application

I don’t know if this step was necessary, but I did it anyway.

That solved the “unknown format: png” error that I was getting. In days like today I love yum.





setting up sendmail in EC2

22 02 2009

Somehow I noticed that our Drupal wasn’t sending email notifications as it was supposed to. We just migrated a CMS to one of our EC2 instances. I figured that Drupal was using sendmail, as I couldn’t find any SMTP configuration in the administration section.

First of all, I checked if sendmail was running:

ps -aux | grep sendmail

That showed me that it wasn’t running.

Then I started it as root:

/usr/sbin/sendmail -bd -q20m

Then I added our domain name to the list of local host names at /etc/mail/local-host-names

Also, I configured submit.cf to use our domain: aycron.com – You can find submit.cf at /etc/mail/submit.cf and modify it to look like this:

# my official domain name
# … define this only if sendmail cannot automatically determine your domain
#Dj$w.Foo.COM
Dj$w.aycron.com

Finally, I tested that sendmail was working:

[etagwerker@dev-001 ~]$ /usr/sbin/sendmail -F”Ernesto Tagwerker” etagwerker@aycron.com
Hello, this is a test. 1. 2. 3. Testing.
Bye.
.

This totally worked!





Rails/Ruby integration with SOAP

15 02 2009

The other day I needed to integrate with Lyris ListManager using their API. Their API uses SOAP and my application is on Rails. I started looking for information about Ruby/Rails + SOAP integration and found this article first: http://wiki.rubyonrails.org/rails/pages/HowToUseSOAP4RWithRails

That’s how I started. Assuming that you have a running SOAP service on mylistmanager.com:82, here are the steps I took:

1. Install soap4r’s gem (if you don’t have it already)

[etagwerker@benteveo]$ sudo gem install soap4r
Password:
Successfully installed httpclient-2.1.3.1
Successfully installed soap4r-1.5.8
2 gems installed
Installing ri documentation for httpclient-2.1.3.1…
Installing RDoc documentation for httpclient-2.1.3.1…

Unfortunately, that rubyonrails.org article was not clear enough for what I wanted to do. Basically, I want to consume a SOAP service. So I needed to create a SOAP client stub that I could use from my application. After googling for information on wsdl2ruby, I found this really good article: http://www.brendonwilson.com/blog/2006/04/02/ruby-soap4r-wsdl-hell

2. Generate your client stub with wsdl2ruby

[etagwerker@benteveo]$ wsdl2ruby.rb –wsdl http://mylistmanager.com:82/?wsdl –type client –force
I, [2009-02-11T11:06:26.012941 #7276]  INFO — app: Creating class definition.
I, [2009-02-11T11:06:26.013108 #7276]  INFO — app: Creates file ‘lmapi.rb’.
I, [2009-02-11T11:06:26.117915 #7276]  INFO — app: Creating mapping registry definition.
I, [2009-02-11T11:06:26.118102 #7276]  INFO — app: Creates file ‘lmapiMappingRegistry.rb’.
I, [2009-02-11T11:06:26.234855 #7276]  INFO — app: Creating driver.
I, [2009-02-11T11:06:26.235469 #7276]  INFO — app: Creates file ‘lmapiDriver.rb’.
I, [2009-02-11T11:06:26.308501 #7276]  INFO — app: Creating client skelton.
I, [2009-02-11T11:06:26.308847 #7276]  INFO — app: Creates file ‘lmapiClient.rb’.
I, [2009-02-11T11:06:26.321677 #7276]  INFO — app: End of app. (status: 0)

This generated a bunch of Ruby files that are very useful for the integration. Basically, it makes everything more simple. You don’t need to worry about SOAP messages, responses, etc.. You just use the classes in that stub to interact with your SOAP service.

3. Move the client stub files to your /lib directory (in your Rails project)

This will make your stub client classes accessible to your application

4. Add soap4r to your boot.rb file

I don’t know where I found this step, but I was getting an error with SOAP when trying to use SOAP classes form my application. Your boot.rb should look like this:

def load_rubygems
require ‘rubygems’
gem ‘soap4r’

Basically, I added gem ‘soap4r’ which imports the SOAP classes in my application.

5. Fire up your Rails console (./script/console in your Rails project) and test it!

Luckily, I found a really thorough example here: http://markthomas.org/2007/09/12/getting-started-with-soap4r - However, if you look at the files you generated with wsdl2ruby, you will find a lot of useful and descriptive information (as code and comments)

To test it, I include the lmapiDriver.rb (present in the /lib directory), I create a driver, I give it the user credentials and I start using it (selectLists and apiVersion are both Lyris SOAP API methods)

require “lmapiDriver.rb”
driver = LmapiSoap.new

#Add authentication
wsdl = “http://mylistmanager.com:82/?wsdl”
user = “yourusername”
pass = “yourpassword”
driver.options["protocol.http.basic_auth"] << [wsdl,user,pass]

# Print the name of all lists
lists = driver.selectLists(”,”)

driver.apiVersion

# If it all worked out fine, you should see:
# => “10.2″

I found this integration really simple. wsdl2ruby.rb is an amazing tool for speeding things up.








Follow

Get every new post delivered to your Inbox.