Feb 11 2008

Server push with Ruby on Rails using Flex, JRuby, and BlazeDS

Tag: ActiveMQ, ActiveMessaging, Flex, Flex and Rails, JRuby, Messaging, Server Push, blazedsDerek Wischusen @ 5:32 am

In a previous post I discussed how you can integrate Flex and Scala/Lift using BlazeDS.  In this post I’ll show that it’s also possible to get Rails running on BlazeDS using JRuby.

Here is what I am using for this example:

You don’t really need Netbeans, but I’ve found that it makes things a bit easier.

For this example I am going to assume you have a basic understanding of Flex and Rails.  That said, if anyone has a question, not matter how basic, please feel free to ask.

Here are the source files if you want to follow along:

—– 

Ok, first lets get the Rails app set up.

1. Create a new Rails app called RoRBlaze.

2. Generate a controller called Greeting with an index view.  i.e.,

> ruby script/generate controller Greeting index

3.  Open up your newly generated greeting.rb file and add the following code:

class GreetingController < ApplicationController
  include Java
  import "flex.messaging.MessageBroker"
  import "flex.messaging.messages.AsyncMessage"
  import "flex.messaging.util.UUIDUtils"

  @@msgBroker = MessageBroker.getMessageBroker(nil)
  @@clientID = UUIDUtils.createUUID()

  def hello
    @msg = AsyncMessage.new()
    @msg.setDestination("notifications")
    @msg.setClientId(@@clientID)
    @msg.setMessageId(UUIDUtils.createUUID())
    @msg.setTimestamp(Time.new.to_f)
    @msg.setBody("Hello from Rails")
    @@msgBroker.routeMessageToService(@msg, nil)
    render :text => "Greeting Sent"
  end
end

4. Open view/greeting/index.rhtml and add a button to it like so,

<%=button_to "Send Greeting to Flex", :action=>"hello" %>

5. Go to the BlazeDS folder and  locate the following two .jar files in tomcat\webapps\blazeds\WEB-INF\lib:

  • flex-messaging-common.jar
  • flex-messaging-core.jar

6. Copy these .jar files into the lib folder in your Rails app (keep this folder open, you’ll need the more of the .jars in a moment).

7. In your Rails app open up config/environment.rb and add the following to the bottom of the file:

Dir["#{RAILS_ROOT}/lib/**/*.jar"].each do |jar|
  require jar
end

Alright, thats pretty much all of the Ruby code for this simple example.  Now we need to use the Goldspike Rails plugin to modify our Rails app so that it can run in a Java server (like Tomcat or Jetty or Glassfish, etc)

8.  From a command line, go to the root of your Rails app and install the Goldspike plugin:

> ruby script/plugin install http://jruby-extras.rubyforge.org/svn/trunk/rails-integration/plugins/goldspike

9. WARify you Rails app using the following rake command:

> rake war:standalone:create

Assuming that Goldspike did its job, you should now have a folder called WEB-INF in the root of you Rails app.  We need to add a few file to this folder to get BlazeDS working.

10. Copy the .jars from BlazeDS\tomcat\webapps\blazeds\WEB-INF\lib into RoRBlaze\WEB-INF\lib

11. Copy the folder BlazeDS\tomcat\webapps\blazeds\WEB-INF\flex into RoRBlaze\WEB-INF

12. Open up the web.xml file in blazeds\WEB-INF and merges its contents into the web.xml file in RoRBlaze\WEB-INF.  Click here to see what the final file should look like.

13. Open up RoRBlaze\WEB-INF\flex\messaging-config.xml and modify it so that it looks like this (click to view the file).  The key thing to note here is that we added a messaging destination called “notifications”.  This is the destination that the Greeting controller publishes to and it is the destination that our Flex app will subscribe to.

14. Open up RoRBlaze\WEB-INF\flex\services-config.xml and modify it so that it looks like this (click to view the file).  The key thing to notice in this file is that we defined a streaming channel called my-streaming-amf that BlazeDS will use to push messages over a persistent, streaming HTTP channel.

That’s it for the Rails app.  Now let’s create the Flex app.

—–

1. Create a new Flex Project (File -> New -> Flex Project)

2. Fill in the rest as follows:

  • Project name: RoRBlaze
  • Application type: Web Application
  • Application server type: J2EE
  • Use remote object access service: check this
  • Root folder: RoRBlaze  (the root folder of your Rails app)
  • Root URL: http://localhost:8080/RoRBlaze/
  • Context root: /RoRBlaze
  • Output folder: RoRBlaze\public
  • Output folder URL: http://localhost:8080/RoRBlaze

3. Open up RoRBlaze.mxml and edit it like so:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
	xmlns:mx="http://www.adobe.com/2006/mxml"
	layout="vertical"
	creationComplete="consumer.subscribe()">

    <mx:Script>
        <![CDATA[
          	import mx.messaging.events.MessageEvent;

            private function messageHandler(message: MessageEvent): void
            {
                pushedMessage.text = message.message.body as String;
            }
        ]]>
    </mx:Script>

    <mx:Consumer
    	id="consumer"
    	destination="notifications"
    	message="messageHandler(event)"
    	channelConnect="trace(event)"
        channelFault="trace(event)"
        fault="trace(event)" />

    <mx:TextInput id="pushedMessage" width="300"/>
</mx:Application>

That’s it for the Flex app.  Let’s test everything out.

—–

1. Open a terminal and go to the root of your Rails app.  Then use Goldspike to boot up your Rails app in a Jetty server:

> rake war:standalone:run

In a few short seconds your Rails app should  be up and running.

2. Launch the Flex app.

3.  Open a browser and enter the following URL: http://localhost:8080/RoRBlaze/greeting

You should see a single button that says “Send Greeting to Flex”

4. Click the button.

Upon clicking the button you should see the browser display “Greeting Sent” and you should see “Hello from Rails” appear in the text input in your Flex app.

That’s it.  Assuming that everything worked properly, the Rails app should have pushed an AMF encoded message to Flex using a persistent streaming HTTP channel created by BlazeDS.

One importatant thing to take note off is that this technique could be useful to you even if you aren’t planning on using Flex/Flash as your presentation layer.  You could use a Juggernaut style approach and push messages from Rails to an embedded Flash player whose only job is to pass those messages along to the browser.

This example demonstrates a very simple way to integrate Flex, Rails, and BlazeDS.  I think the ideal way to integrate these technologies would be to use the ActiveMessaging plugin for Rails, since both ActiveMessaging and BlazeDS have JMS adapters which they could use to integrate with a more robust messaging system like ActiveMQ.  If I can find some time in the near future, and if there is any interest, I’ll do a follow up post on this.


Jan 24 2008

Integrating Flex, BlazeDS, and Scala/Lift

Tag: AMF, Flex, Remoting, Server Push, blazeds, lift, scala, tutorialDerek Wischusen @ 6:00 am

A short while ago Adobe announced that they would be releasing an open source version of LiveCycle Data Services called BlazeDS. In short, BlazeDS is Java technology that makes it really easy to do HTTP streaming and server-side push to Flex and AIR applications. While this announcement is definitely welcome news, there may be a lot of people out there who thought to themselves, “That’s great, but I don’t use Java.” Well, the good news is that just because BlazeDS uses Java the platform doesn’t mean that you necessarily need to use Java the language to take advantage of it.

In fact, Java the platform supports several different languages, including Groovy, Python, Ruby, and Scala. And, of course, ColdFusion. In theory, it should be pretty straight-forward to integrate any of these languages with BlazeDS.

For the rest of this post I am going to focus on just one of them, Scala. Why Scala? Well, it is because recently I decided that I wanted to broaden my programming language horizons and I’ve found that Scala is both extremely interesting and very powerful. It’s both object-oriented and functional, it has mixin style composition, it has an exceptional implementation of Erlang style Actors for handling concurrency, and much more. Lastly, and perhaps most important for my purposes, there is an excellent webapp framework for Scala called Lift.

All right, let’s get started with integrating Flex, BlazeDS, and Scala/Lift.

Prerequisites – latest versions of:

—–

If you’d like to follow along with source files, here they are.

Source Code:

—–

First, let’s create a Lift project named LiftBlaze:

1. Open a terminal and navigate to the directory where you want to create the project.

2. Enter the following command:

mvn archetype:create -U                                    \
-DarchetypeGroupId=net.liftweb                             \
-DarchetypeArtifactId=lift-archetype-blank                 \
-DarchetypeVersion=0.4                                     \
-DremoteRepositories=http://scala-tools.org/repo-releases  \
-DgroupId=org.rxr.liftblaze -DartifactId=liftblaze

3. Next enter:

cd liftblaze

4. Lastly, enter:

mvn jetty:run

If everything worked properly, then you should see a “Hello World” welcome page at http://localhost:8080/

—–

Next, let’s use Maven to create an eclipse project for us:

1. In a terminal, go to lift linkblaze project and enter:

mvn eclipse:eclipse

You should now be able to import the linkblaze project into Eclipse. Once you have the project imported you will need to add the BlazeDS jars to your build path. These jars are located in {blazeds_folder}\tomcat\webapps\blazeds\WEB-INF\lib.

—–

Now let’s start setting up the Lift project to work with Flex and BlazeDS.

1. Open the web.xml file located in {blazeds_folder}\tomcat\webapps\blazeds\WEB-INF

2. Open the web.xml file located in liftblaze\src\main\webapp\WEB-INF.

3. Copy the contents of the web.xml file from the BlazeDS folder into the web.xml file in the liftblaze Lift project.

At this point, it would be useful to talk a bit about how lift handles HTTP requests. Lift is a view first framework. What this means is that by default lift will try to match an HTTP request against one its views. If it finds one it will do some processing on it, and then render it our as HTML. For more info on how Lift handles HTTP requests, check out this page.

For this project, the entire view is going to be in Flex, so we don’t really Lift want to concerned about the view we just want it to handle our web service calls. To achieve this do the following:

4. Inside you newly merged web.xml file, modify the filter-mapping tag like so:

<filter-mapping>
  <filter-name>LiftFilter</filter-name>
  <url-pattern>/webservices/*</url-pattern>
</filter-mapping>

Now Lift will only handle requests that start with webservices. In a later step we will tell Lift how to route these calls so that they invoke methods on a class that we will define.
5. Copy {blazeds_folder}\tomcat\webapps\blazeds\WEB-INF\flex into liftblaze\src\main\webapp\WEB-INF

6. Inside the flex folder, open the messaging-config.xml file and add the following:

 <destination id="notifications">
     <channels>
         <channel ref="my-streaming-amf"/>
     </channels>
 </destination>

This is the messaging destination that our Lift app will publish to and that our Flex app will subscribe to.

—–

All right, let’s start adding some Scala code to our lift project.

1. In Eclipse, create a package called org.rxr.liftblaze.actor

2. In this package, create a Scala Class called Notifier and add the following code to it:

package org.rxr.liftblaze.actor;

import flex.messaging.MessageBroker
import flex.messaging.messages.AsyncMessage
import flex.messaging.util.UUIDUtils
import scala.actors._
import scala.actors.Actor._
import compat.Platform._
import net.liftweb.util._
import org.rxr.liftblaze.model.Notification

class Notifier extends Actor {

  val msgBroker = MessageBroker.getMessageBroker(null)
  val clientID = UUIDUtils.createUUID()
  val msg = new AsyncMessage() 

  var notificationsSent = 0;

  def act{

    ActorPing.schedule(this, Notify, 500L)

    loop {
      react {

        case Notify =>
          msg.setDestination("notifications")
          msg.setClientId(clientID)
          msg.setMessageId(UUIDUtils.createUUID())
          msg.setTimestamp(currentTime)
          msg.setBody(new Notification(notificationsSent, "Hello from Scala/Lift", new java.util.Date()))
          msgBroker.routeMessageToService(msg, null)
          notificationsSent+=1
          println("notification sent at " + currentTime)
          ActorPing.schedule(this, Notify, 500L)       

        case "stop" =>
          exit()
      }
    }
  }

}

case object Notify

This is class that does the majority of the work in this simple application. The first thing to note about it is that it is a Scala Actor. I don’t want to go into too much detail about Actors here. For this tutorial we can grossly oversimplify and say that an Actor is kind of like a thread that can send and receive messages. If you want to get the full story you can click on the preceding link.

Here is a very brief explanation of what is happening in this class. When the Notifier Actor is started (you’ll see where this happens later) the act method is called. The first thing inside the act method is a call to the ActorPing.schedule helper method. This method basically says that I want to send a Notify message to this Actor in 500 milliseconds. Next comes loop which simply creates a loop and then react which has case statements that are used to handle incoming messages. So, when react receives a Notify or a “stop” message all of the code for that case is executed.

When a Notify is received a message is published to the “notifications” destination that we created earlier in the message-config.xml file. Once the message is sent, there is another call to ActorPing.schedule which will send another Notify message in 500 milliseconds. So, until a “stop” method is received, the Notifier Actor will publish a notification every 500 milliseconds.

The body of the message that is being published is a custom Scala class called Notification. One of the benefits of BlazeDS is that you can use the AMF protocol to send strongly typed objects from the server to your Flex client. So I can have BlazeDS serialize my Notification class in Lift down into AMF binary and then have it reappear as a Notification class in Flex, which is pretty handy. Though I have found that there is one small trick to creating classes in Scala that will serialize properly. To illustrate, let’s create the Notification class next.

3. Create a Scala Class named Notification in 0rg.rxr.liftblaze.model and add the following code,

package org.rxr.liftblaze.model

import java.util.Date

class Notification(var id: Int, var message: String, var timesent: Date)
{
    def getId = id
    def setId(id: Int) = this.id = id

    def getMessage = message
    def setMessage(m: String) = message = m

    def getTimesent = timesent
    def setTimesent(t: Date) = timesent = t
}

The main thing to take note of here is that I am using methods that are named like Java (the language) getters and setters, rather than variables. This is because the Scala compiler takes variables defined in Scala and turns them into methods in Java. So,

val greeting = "Hello"

in Scala becomes

public String greeting()
{
  return "Hello"
}

in Java. The same goes for var (FYI, vals are immutable variables, while vars are mutable). So, member variables in Scala won’t serialized by BlazeDS because they turn into methods in Java. The solution, as I have already shown, is just to use methods in Scala that are named like Java getters and setters.

Now that we’ve seen who is sending the messages in Lift (the Notifier Actor) and what is being sent (the Notification class), let’s create the class that starts and stops the Notifier.

4. In org.rxr.liftblaze.controller create a Scala Class called WebServices and then add the following code

package org.rxr.liftblaze.controller

import net.liftweb.http._
import javax.servlet.http.{HttpServlet, HttpServletRequest , HttpServletResponse, HttpSession}
import org.rxr.liftblaze.actor.Notifier

class WebServices (val request: RequestState,val httpRequest: HttpServletRequest) extends SimpleController {

  def start_feed = {
    WebServices.notifier.start()
    XmlResponse(<start_feed success="true"/>)
  }

  def stop_feed = {
    WebServices.notifier ! "stop"
    XmlResponse(<stop_feed success="true"/>)
  }
}

object WebServices {
  val notifier = new Notifier()
}

This is class is pretty much self explanatory. The start_feed method calls start on our Notifier Actor, which as we discussed causes the Notifier to send out a Notification every 500 milliseconds. The stop_feed method sends a “stop” message to the Notifier, which causes it to exit. Both methods return a simple XML response.

We’re almost done with the Lift app, just one more thing to do. In a previous step we modified the web.xml file so that Lift would only handle requests that start with webservices. Now we just need to tell Lift how to process/route those request so that they call the method in our WebServices class. To do this we need to modify the Boot class.

5. Open the Boot class located in bootstrap.liftweb and modify it thusly

package bootstrap.liftweb

import net.liftweb.util._
import net.liftweb.http._
import Helpers._
import org.rxr.liftblaze.controller.WebServices
import javax.servlet.http.{HttpServlet, HttpServletRequest , HttpServletResponse, HttpSession}

/**
  * A class that's instantiated early and run.  It allows the application
  * to modify lift's environment
  */
class Boot {
  def boot {

    val dispatcher: LiftServlet.DispatchPf = {
     // if it's a web service, pass it to the web services invoker
     case RequestMatcher(r, ParsePath("webservices" :: c :: _, _,_),_, _) => invokeWebService(r, c)
    }
    LiftServlet.addDispatchBefore(dispatcher)

  }

  private def invokeWebService(request: RequestState, methodName: String)(req: HttpServletRequest): Can[ResponseIt] =
    createInvoker(methodName, new WebServices(request, req)).flatMap(_() match {
    case Full(ret: ResponseIt) => Full(ret)
    case _ => Empty
  })
}

This code is taken directly from the examples included with the Lift source code. In Basic terms, this code matches a request that starts with webservices and passes the request and method name to be invoked to the invokeWebService method. This method the calls createInvoker which invokes the method on our WebServices class. So, for example http://localhost:8080/webservices/start_feed would call the start_feed method on the WebServices class. You can read more about how this code works here.

That’s it for the Lift App. All in all there really isn’t that much code. Though, of course, this app is pretty simple. Regardless of how simple this app is, I would say that in the short time that I have been using Scala I have found it to be the most concise statically typed language that I have ever used.

—–

Now let’s create the Flex App in Flex Builder.

1. Create a new Flex Project (File -> New -> Flex Project)

2. Fill in the rest as follows:

Project name: LiftBlaze

Application type: Web Application

Application server type: J2EE

Use remote object access service: check this

Root folder: {liftblaze_lift_app}\src\main\webapp

Root URL: http://localhost:8080/

Context root: /

Output folder: {liftblaze_lift_app}\src\main\webapp

Output folder URL: http://localhost:8080/

3. Once you have everything filled out, click Finish

All right, now that we have the project created let’s add some code to it.

4. Open LiftBlaze.mxml and add the following code:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" >
    <mx:Script>
        <![CDATA[
        	import org.rxr.liftblaze.model.Notification;
          	import mx.messaging.events.MessageEvent;

            private function messageHandler(message: MessageEvent): void
            {
            	var notification : Notification = message.message.body as Notification;
                pushedValue.htmlText = "<b>id:</b> " + notification.id + " <b>Date:</b> " + notification.timesent;
            }    

        ]]>
    </mx:Script>

    <mx:Consumer
    	id="consumer"
    	destination="notifications"
    	message="messageHandler(event)"
    	channelConnect="trace(event)"
        channelFault="trace(event)"
        fault="trace(event)" />

    <mx:HTTPService
    	id="startFeed"
    	url="webservices/start_feed"
    	result="consumer.subscribe()" />
    <mx:HTTPService
    	id="stopFeed"
    	url="webservices/stop_feed"
    	result="consumer.unsubscribe()" />

 	<mx:Button
 		label="Subscribe to 'notifications'"
 		click="startFeed.send({stop_cache: new Date().getMilliseconds()})"
 		enabled="{!consumer.subscribed}"/>

	<mx:Button
		label="Unsubscribe from 'notifications'"
		click="stopFeed.send({stop_cache: new Date().getMilliseconds()})"
		enabled="{consumer.subscribed}"/>

    <mx:TextInput id="pushedValue" width="300"/>
</mx:Application>

What we’ve create here is an app that has a very simple UI that consists of two buttons and a text input field. The app also has two HTTPServices and Consumer. A couple of things to take note of here. First, the Consumer subscribes to the “notifications” destination, the same destination that our Notifier Actor publishes its messages to. Second, the HTTPServices make calls to webservices/start_feed and webservices/stop_feed. If you’ll recall we set up our Lift app so that these calls would be routed to invoke the methods in our WebServices class.

We just need to add one last piece of code to get everything working properly. In our Lift app the Notifier Actor sends out instances of the Notification class that we created. Now we need to create a corresponding Notification class in our Flex app so that when we receive the data in Flex it will show up as strongly typed class.

5. Create a Class named Notification in org.rxr.liftblaze.model and add the following code

 package org.rxr.liftblaze.model
{
    [Bindable]
    [RemoteClass(alias="org.rxr.liftblaze.model.Notification")]
    public class Notification
    {
        public var id : int;
        public var timesent : Date;
        public var message: String;

        public function Notification()
        {
            super();
        }

    }
}

You’ll notice that this class has the same attributes as the Scala Notification class in our Lift app. The key to mapping this class to our Scala class is the RemoteClass metadata tag located just above the class definition. This tag is used to tell Flex the fully qualified name of the server side class that this class maps to.

—–

That should be it. You now be able to boot up you Lift app, launch the Flex app, click the “Subscribe to ‘notifications’” to start the Notifier Actor and subscribe to the Consumer to the notifications destination. You should then see id number and the time in the text input field get automatically updated every 0.5 seconds. You can the click the “Unsubscribe from ‘notifications’” to stop the Notifier actor and the Consumer to unsubscribe from the notifications destination.

Pretty exciting. With these three technologies it’s really easy to automatically push data from the server to the client in real time. This is obviously a trivial example, but I think it should be relatively straight forward to scale this approach up for more sophisticated apps.

That wraps this up. Please let me know if you have any questions.


Discount viagra usa
Viagra prescription cost
Viagra online purchase in india
Phentermine purchase online
Best levitra prices
Cialis medication
Valium online uk
Viagra canada mastercard
Buy viagra online cheap
Viagra shop online
Propecia generic online
Phentermine 37.5 mg
Buy cialis viagra
Prescription valium
Cialis 20 mg dosage
Buy levitra online canada
Buy brand name viagra
Fedex tramadol
Where to buy viagra in england
Generic xanax no prescription
Buy viagra uk no prescription
Cheap xanax for sale
Buy generic cialis online
Cialis online canadian pharmacy
Viagra prescription
Buy viagra uk online
Valium 10 mg
Buying levitra without prescription
Xanax for sale without prescription
Prescription viagra uk
Phentermine with no prescription
Buy pfizer viagra without prescription
Order tramadol online cod
Order xanax cod
Xanax no prescription required
Viagra purchase uk
Buy propecia cheap
Buying cialis
Buy tramadol cod
Viagra 50 mg online without prescription
Viagra online shop
Where can i buy viagra in the uk
Propecia generic canada
Best viagra alternative
Tramadol india
Buy viagra online uk no prescription
Cialis prices uk
Tramadol prescription online
Best price on phentermine
Low cost levitra
Xanax 1mg side effects
Propecia usa
Buy viagra in england
Tramadol for sale
Phentermine canada no prescription
Buying xanax online without prescription
Ordering cialis online
Buy generic cialis uk
Cheapest place to buy viagra online
Tramadol without prescription overnight delivery
Levitra price
Phentermine hcl no prescription
Cheapest cialis price
Prednisone online
Cheap cialis pills
Phentermine 37.5 buy online
Phentermine online uk
Xanax bars dosage
Viagra express delivery
Order tramadol cod
Free cialis samples
Cheapest cialis professional
Prescription free viagra
Viagra for sale online
Cheap levitra uk
Prednisone tablets 10 mg
How to buy phentermine online
Dose of xanax
Generic viagra online without prescription
Cheapest generic viagra online
Cialis price
Buying viagra online
Viagra discount coupons
Australia viagra online
Propecia 1mg generic
How to buy valium without a prescription
Buy female viagra without prescription
Where can i buy cialis without a prescription
Canada pharmacy valium
Genuine viagra online
Buy propecia
Best way to buy viagra online
Viagra indian pharmacy
Valium drug side effects
Generic xanax xr
Prescriptions for phentermine
Buy cheap viagra online uk
Tramadol medication
100mg tramadol effects
Viagra online uk
Propecia cost
Cialis samples canada
Generic propecia

Buy phentermine no rx
Tramadol pharmacy
Online prescriptions xanax
Cialis 20mg side effects
Order phentermine online no prescription
Xanax bars effects
Cialis prescription cost
Low price viagra
Phentermine buy australia
Order cheap viagra online
Prescription phentermine online
Buy viagra online in ireland
Cialis dosage 20mg
Purchase xanax
Valium from india
Buy xanax overnight
Cheap cialis
Generic tramadol
Buy generic propecia uk
Cialis 10mg side effects
Phentermine hcl without prescription
Free samples of cialis
Buying viagra in london
Buy tramadol hcl
Buy generic valium online
Phentermine online free shipping
Buy viagra online in australia
Tramadol free shipping
Brand viagra cheap
Get viagra
Viagra ordering
Best price cialis
Buy xanax online without prescription
Purchase tramadol without prescription
Viagra pharmacy prices
Cheap cialis soft tabs
Online valium without prescription
Propecia price australia
Get tramadol prescription
Purchase phentermine without prescription
Viagra pharmacy uk
Propecia information
Where can i buy viagra without a prescription
Viagra price canada
Phentermine 37.5 pills
Order prednisone no prescription
Best way to take tramadol
Xanax no rx
Phentermine without a prescription
Discount viagra online
Phentermine cheap online
Pfizer viagra price
Buying prednisone online
Where to buy cialis without prescription
Purchase tramadol online
Viagra india price
Where to buy propecia in canada
Best prices for cialis
Xanax bars side effects
Generic cialis tadalafil
Canada viagra no prescription
Cialis discount price
Xanax buy uk
Viagra in the uk
Cheap 37 5 phentermine
Xanax no prescription overnight
Best viagra dose
Cheap phentermine without prescription
Where to buy cialis online
Generic xanax
Cialis order online
Tramadol no prescription overnight delivery
Viagra generic cheap
Tramadol dosage
Phentermine canadian pharmacy
Viagra canada prices
Viagra tablets for sale
Viagra 50mg side effects
Buy generic phentermine online
Cheap xanax bars
Propecia generic cost
Overnight xanax delivery
Valium pill 10mg
Viagra online without prescription reviews
Purchase phentermine
Buy generic valium
Discount viagra pills
Viagra generic
Buying valium in spain
Buy cialis online from canada
Viagra fast delivery
Order xanax online
Generic viagra for sale
Xanax generic dosage
Viagra pills for sale
Cheap generic valium
Buy cialis brand
Overnight tramadol no prescription
Viagra buy online no prescription
Cheap 100mg viagra
Cialis purchase online
Tramadol online overnight
Viagra in france
2.5mg cialis
Phentermine 37.5mg side effects
Buy tramadol overnight
Prednisone dosages
Viagra no prescription online
Cheap cialis india
Buy propecia online without a prescription
Propecia cheap
Cialis for sale
Valium no rx
Pharmacy tramadol
Xanax overnight cod
Buy phentermine no script
Valium online fast delivery
Generic viagra super active
Generic cialis uk
Overnight delivery viagra
Viagra sale uk
Cialis soft tabs online
Buy generic cialis
Phentermine 37.5 wholesale
40 mg prednisone side effects
Viagra online cheap
Buy xanax cheap online
Prescription propecia
Prednisone tablets
Valium without prescription uk
Generic viagra 100mg
Buy cheap valium online
Viagra super active
Order cheap phentermine
Where to buy levitra online
Tramadol without prescription
Blood pressure and prednisone
Cost of viagra 50mg
Buy viagra in canada online
Where to buy phentermine cheap
Side effects of viagra
Purchase cialis without a prescription
Tramadol cod delivery
Valium generic
Low price cialis
Xanax 1mg