koala response times. 20 seconds waiting response - ruby-on-rails

I'm new with Rubyonrails and Koala gem and I'm sure I'm doing something wrong. I've been tuning my code to the minimun expression but the problem persist. Then I tried to do the same without koala gem, but the problem persisted.
This is the code:
require 'koala'
require 'open-uri'
puts Time.now
#graph = Koala::Facebook::API.new
resp = #graph.graph_call("cocacola", {}, "get", {})
puts resp
puts Time.now
coke_url = "https://graph.facebook.com/cocacola"
response = open coke_url
response = JSON.parse response.read
puts response.inspect
puts Time.now
I have to wait always 21 seconds the Facebook's response. If I put the https://graph.facebook.com/cocacola on my browser, the response is instantaneous ¿is not the same?
thanks

I'm using Koala in my application and did not have such experience. The only difference is that I don't use it anonymously. Instead I created an app and I'm using an access token to access the Facebook API. This might be the root cause, as I've found this post that also seems relates.

Finally, it was a DNS problem (thanks jpgeek).
When I did just a GET request to any website, the response was after 21 seconds, but using the IP of the same website, the response was instantaneously.
I found on google the solution: http://www.mikeperham.com/2010/02/10/asynchronous-dns-resolution/
I have use this personal solution in Gemfile (I'm not sure if it's the best):
group :development do
require 'resolv'
require 'resolv-replace'
end
Now it's working fine!

Related

How to check for successful response from API in rails by just using status code?

I am consuming an API using a gem in Ruby on Rails. The gem makes the API call for me and returns the status code as an integer (for example 200, 201 e.t.c.) and the data response from the API.
def get_cars
status_code, data = MyGem::Cars.get_cars
if status_code in SUCCESSFUL_RESPONSE_CODES
# Perform data manipulation
else
raise "There was an error processing the request. Status code #{status_code}"
end
end
Now I have manually initialised SUCCESSFUL_RESPONSE_CODES as a list containing integers of successful codes I found here.
Is this list defined somewhere in Ruby/RoR to avoid manually defining it?
I would expect any widely supported gem to use standard HTTP response codes to determine if the HTTP response was a success. For example:
require 'open-uri' # Rails loads this by default.
res = open('http://example.com')
res.status
=> ["200","OK"]
status.include?'OK'
=>true
status.include?'200'
=> true
So long as you trust the gem code making your request to handle standard HTTP response codes, you should be ok. Here's another example using HTTParty gem
require 'HTTParty'
res = HTTParty.get('https://example.com')
res.success?
=> true

Undefined method `OAuth' when making HTTP request to Twitter api

I'm getting the following OAuth error when trying to make a request to the Twitter streaming api:
"#NoMethodError: undefined method `OAuth' for #TwitterMoment:0x007fa081d821f0"
def query
authorisation_header = OAuth oauth_consumer_key=ENV["oauth_consumer_key"], oauth_nonce=ENV["oauth_nonce"], oauth_signature=ENV["oauth_signature"], oauth_signature_method=ENV["oauth_signature_method"], oauth_timestamp=ENV["oauth_timestamp"], oauth_token=ENV["oauth_token"], oauth_version=ENV["oauth_version"]
response = HTTParty.get("https://stream.twitter.com/1.1/statuses/filter.json?locations=-#{#bounds}", headers: {"Authorization" => authorisation_header})
end
OAuth is included in my gemfile.
Any ideas would be very much appreciated! This is my first Stack Overflow question :)
You're using OAuth here as a function/method, but that method doesn't exist. There's no def OAuth(...) anywhere in the oauth gem, so it explodes and gives you that NoMethodError.
Judging from the Header example at the bottom of this question, I think you've confused the header string for Ruby code.
Instead, you either need to make the string yourself (a bit annoying to do safely), or use the OAuth gem's methods (API) to do so.
Here's an example from the OAuth github repo:
consumer = OAuth::Consumer.new(
options[:consumer_key],
options[:consumer_secret],
:site => "http://query.yahooapis.com"
)
access_token = OAuth::AccessToken.new(consumer)
response = access_token.request(
:get,
"/v1/yql?q=#{OAuth::Helper.escape(query)}&format=json"
)
rsp = JSON.parse(response.body)
pp rsp
This example may work for you (I'm not able to test it locally here, sorry):
def query
consumer = OAuth::Consumer.new(
ENV["oauth_consumer_key"],
ENV["oauth_consumer_token"],
site: "https://stream.twitter.com"
)
access_token = OAuth::AccessToken.new(consumer)
response = access_token.request(
:get,
"/1.1/statuses/filter.json?locations=-#{OAuth::Helper.escape(#bounds)}"
)
response = JSON.parse(response.body)
pp response # Just a bit of debug printing for the moment; remove this later.
response
end
An addendum:
Usually I might have directed you to use an existing Twitter client gem, such as https://github.com/sferik/twitter, but in this case it looks like they haven't implemented the Moments API yet.

Rails: OAuth2 gem returns 400 error when attempting to connect to facebook

I'm attempting to add Facebook connect to our web app, and I'm running into a problem with. Everything works fine locally (I can authenticate through Facebook), but when I push the code to our dev server (which lives in the wild), every time I try to authenticate it returns the following error code:
OAuth2::HTTPError: Received HTTP 400 during request
That's really the only explanation I'm getting. Again, this works on my local machine, and the gems and such match between boxes, so I'm a bit confused. Here's the code I'm executing.
def facebook_connect
#Set the scope we want to pull from Facebook, along with the callback URL
options = {
:redirect_uri => facebook_callback_url,
:scope => "email,publish_stream"
}
#Go out and fetch the url
client = OAuth2::Client.new(FACEBOOK_API_KEY, FACEBOOK_SECRET, {:site => FACEBOOK_API_URL, :access_token_method => :post})
#Redirect to the callback for processing
redirect_to client.web_server.authorize_url(options)
end
def facebook_callback
#Client URL
client = OAuth2::Client.new(FACEBOOK_API_KEY, FACEBOOK_SECRET, {:site => FACEBOOK_API_URL, :access_token_method => :post})
#Parse out the access token
access_token = client.web_server.get_access_token(params[:code], :redirect_uri => facebook_callback_url)
#Get the user
fb_user = JSON.parse(access_token.get('/me'))
#Do some authentication database stuff
end
def facebook_callback_url
uri = URI.parse(request.url)
uri.path = '/users/facebook_callback'
uri.query = nil
uri.to_s
end
I searched Google, but the solutions that show up aren't working. Also, if anyone knows how to parse and display OAuth2 errors, I would appreciate that, as well. Thanks
Assuming that Facebook OATH knows of your server's IP address(they are very strict about it), I would recommend that you use use 'rescue' to catch that exception, get the backtrace and then find where it is being raised and place a bunch of debug statements to check the state of both request and the response, as well as access tokens.
Or you can configure remote debugging with Rubymine or NetBeans which is not an easy task :)
The issue actually ended up being a problem with the "Faraday" gem. Our dev server wasn't set up to handle SSL, which was returning an error code. We patched it using the following answer:
OmniAuth & Facebook: certificate verify failed

Rails app using Oauth to post to Twitter, getting "not authorized" when running in production server. OK in localhost

I'm trying to use Twitter's Oauth Single Token for posting from a rails app to my twitter feed (single user use-case is perfect for my app). This Is what I'm talking about.
Here's the relevant part of my code:
twitter_consumer_key = 'AAAAAA...'
twitter_consumer_secret = 'BBBBBB///'
oauth_token = 'CCCCC....'
oauth_token_secret = 'DDD.....'
consumer = OAuth::Consumer.new(twitter_consumer_key, twitter_consumer_secret, :site => "http://api.twitter.com", :scheme => :header)
access_token = OAuth::AccessToken.from_hash(consumer, :oauth_token => oauth_token, :oauth_token_secret => oauth_token_secret)
response = access_token.post("http://api.twitter.com/1/statuses/update.json", {:status => "Coffee's ready at 191 Peachtree!! "+Time.now.to_i.to_s})
logger.info response.inspect
When I run this in my local machine, everything goes well and the post is created on my feed. When I run it on my production server (centos5.5, Apache 2, Passenger, Rails 3.0.4) I get "HTTPUnauthorized".
Any ideas on how to troubleshoot this?
Thanks in advance.
Try with filling Callback URL in settings of your application on dev.twitter.com.
Should be something like that:
Callback URL http://yousite.com/auth/twitter/callback
Per abraham's comment, I'm adding the solution as an answer instead of a comment:
My server's timezone was incorrectly set so I was getting the following error in the response body:
{"request":"\/1\/statuses\/update.json","error":"Timestamp out of bounds"}
I set the time and timezone correctly and now it's working fine.
:)

What's the best way to use SOAP with Ruby?

A client of mine has asked me to integrate a 3rd party API into their Rails app. The only problem is that the API uses SOAP. Ruby has basically dropped SOAP in favor of REST. They provide a Java adapter that apparently works with the Java-Ruby bridge, but we'd like to keep it all in Ruby, if possible. I looked into soap4r, but it seems to have a slightly bad reputation.
So what's the best way to integrate SOAP calls into a Rails app?
I built Savon to make interacting with SOAP webservices via Ruby as easy as possible.
I'd recommend you check it out.
We used the built in soap/wsdlDriver class, which is actually SOAP4R.
It's dog slow, but really simple. The SOAP4R that you get from gems/etc is just an updated version of the same thing.
Example code:
require 'soap/wsdlDriver'
client = SOAP::WSDLDriverFactory.new( 'http://example.com/service.wsdl' ).create_rpc_driver
result = client.doStuff();
That's about it
We switched from Handsoap to Savon.
Here is a series of blog posts comparing the two client libraries.
I also recommend Savon. I spent too many hours trying to deal with Soap4R, without results. Big lack of functionality, no doc.
Savon is the answer for me.
Try SOAP4R
SOAP4R
Getting Started with SOAP4R
And I just heard about this on the Rails Envy Podcast (ep 31):
WS-Deathstar SOAP walkthrough
Just got my stuff working within 3 hours using Savon.
The Getting Started documentation on Savon's homepage was really easy to follow - and actually matched what I was seeing (not always the case)
Kent Sibilev from Datanoise had also ported the Rails ActionWebService library to Rails 2.1 (and above).
This allows you to expose your own Ruby-based SOAP services.
He even has a scaffold/test mode which allows you to test your services using a browser.
I have used HTTP call like below to call a SOAP method,
require 'net/http'
class MyHelper
def initialize(server, port, username, password)
#server = server
#port = port
#username = username
#password = password
puts "Initialised My Helper using #{#server}:#{#port} username=#{#username}"
end
def post_job(job_name)
puts "Posting job #{job_name} to update order service"
job_xml ="<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ns=\"http://test.com/Test/CreateUpdateOrders/1.0\">
<soapenv:Header/>
<soapenv:Body>
<ns:CreateTestUpdateOrdersReq>
<ContractGroup>ITE2</ContractGroup>
<ProductID>topo</ProductID>
<PublicationReference>#{job_name}</PublicationReference>
</ns:CreateTestUpdateOrdersReq>
</soapenv:Body>
</soapenv:Envelope>"
#http = Net::HTTP.new(#server, #port)
puts "server: " + #server + "port : " + #port
request = Net::HTTP::Post.new(('/XISOAPAdapter/MessageServlet?/Test/CreateUpdateOrders/1.0'), initheader = {'Content-Type' => 'text/xml'})
request.basic_auth(#username, #password)
request.body = job_xml
response = #http.request(request)
puts "request was made to server " + #server
validate_response(response, "post_job_to_pega_updateorder job", '200')
end
private
def validate_response(response, operation, required_code)
if response.code != required_code
raise "#{operation} operation failed. Response was [#{response.inspect} #{response.to_hash.inspect} #{response.body}]"
end
end
end
/*
test = MyHelper.new("mysvr.test.test.com","8102","myusername","mypassword")
test.post_job("test_201601281419")
*/
Hope it helps. Cheers.
I have used SOAP in Ruby when i've had to make a fake SOAP server for my acceptance tests. I don't know if this was the best way to approach the problem, but it worked for me.
I have used Sinatra gem (I wrote about creating mocking endpoints with Sinatra here) for server and also Nokogiri for XML stuff (SOAP is working with XML).
So, for the beginning I have create two files (e.g. config.rb and responses.rb) in which I have put the predefined answers that SOAP server will return.
In config.rb I have put the WSDL file, but as a string.
##wsdl = '<wsdl:definitions name="StockQuote"
targetNamespace="http://example.com/stockquote.wsdl"
xmlns:tns="http://example.com/stockquote.wsdl"
xmlns:xsd1="http://example.com/stockquote.xsd"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns="http://schemas.xmlsoap.org/wsdl/">
.......
</wsdl:definitions>'
In responses.rb I have put samples for responses that SOAP server will return for different scenarios.
##login_failure = "<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<LoginResponse xmlns="http://tempuri.org/">
<LoginResult xmlns:a="http://schemas.datacontract.org/2004/07/WEBMethodsObjects" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:Error>Invalid username and password</a:Error>
<a:ObjectInformation i:nil="true"/>
<a:Response>false</a:Response>
</LoginResult>
</LoginResponse>
</s:Body>
</s:Envelope>"
So now let me show you how I have actually created the server.
require 'sinatra'
require 'json'
require 'nokogiri'
require_relative 'config/config.rb'
require_relative 'config/responses.rb'
after do
# cors
headers({
"Access-Control-Allow-Origin" => "*",
"Access-Control-Allow-Methods" => "POST",
"Access-Control-Allow-Headers" => "content-type",
})
# json
content_type :json
end
#when accessing the /HaWebMethods route the server will return either the WSDL file, either and XSD (I don't know exactly how to explain this but it is a WSDL dependency)
get "/HAWebMethods/" do
case request.query_string
when 'xsd=xsd0'
status 200
body = ##xsd0
when 'wsdl'
status 200
body = ##wsdl
end
end
post '/HAWebMethods/soap' do
request_payload = request.body.read
request_payload = Nokogiri::XML request_payload
request_payload.remove_namespaces!
if request_payload.css('Body').text != ''
if request_payload.css('Login').text != ''
if request_payload.css('email').text == some username && request_payload.css('password').text == some password
status 200
body = ##login_success
else
status 200
body = ##login_failure
end
end
end
end
I hope you'll find this helpful!
I was having the same issue, switched to Savon and then just tested it on an open WSDL (I used http://www.webservicex.net/geoipservice.asmx?WSDL) and so far so good!
https://github.com/savonrb/savon

Resources